// ********************************************************************** // // Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. // // This copy of Ice-E is licensed to you under the terms described in the // ICEE_LICENSE file included in this distribution. // // ********************************************************************** #include #include #include #include #include #include #include #ifdef ICEE_HAS_ROUTER # include # include # include #endif #ifdef ICEE_HAS_LOCATOR # include # include #endif #include #include #include #include #include using namespace std; using namespace Ice; using namespace IceInternal; void IceInternal::incRef(IceInternal::Reference* p) { p->__incRef(); } void IceInternal::decRef(IceInternal::Reference* p) { p->__decRef(); } const Context& IceInternal::Reference::getContext() const { return _hasContext ? _context : _instance->getDefaultContext(); } ReferencePtr IceInternal::Reference::defaultContext() const { if(!_hasContext) { return ReferencePtr(const_cast(this)); } ReferencePtr r = _instance->referenceFactory()->copy(this); r->_hasContext = false; r->_context.clear(); return r; } CommunicatorPtr IceInternal::Reference::getCommunicator() const { return _communicator; } ReferencePtr IceInternal::Reference::changeContext(const Context& newContext) const { if(_hasContext && newContext == _context) { return ReferencePtr(const_cast(this)); } ReferencePtr r = _instance->referenceFactory()->copy(this); r->_hasContext = true; r->_context = newContext; return r; } ReferencePtr IceInternal::Reference::changeMode(Mode newMode) const { if(newMode == _mode) { return ReferencePtr(const_cast(this)); } ReferencePtr r = _instance->referenceFactory()->copy(this); r->_mode = newMode; return r; } ReferencePtr IceInternal::Reference::changeIdentity(const Identity& newIdentity) const { if(newIdentity == _identity) { return ReferencePtr(const_cast(this)); } ReferencePtr r = _instance->referenceFactory()->copy(this); r->_identity = newIdentity; return r; } ReferencePtr IceInternal::Reference::changeFacet(const string& newFacet) const { if(newFacet == _facet) { return ReferencePtr(const_cast(this)); } ReferencePtr r = _instance->referenceFactory()->copy(this); r->_facet = newFacet; return r; } ReferencePtr IceInternal::Reference::changeDefault() const { ReferencePtr r = _instance->referenceFactory()->copy(this); r->_mode = ModeTwoway; r->_secure = false; r->_hasContext = false; r->_context.clear(); r->_facet = ""; return r; } Int Reference::hash() const { IceUtil::Mutex::Lock sync(_hashMutex); if(_hashInitialized) { return _hashValue; } string::const_iterator p; Context::const_iterator q; Int h = static_cast(_mode); for(p = _identity.name.begin(); p != _identity.name.end(); ++p) { h = 5 * h + *p; } for(p = _identity.category.begin(); p != _identity.category.end(); ++p) { h = 5 * h + *p; } if(_hasContext) { for(q = _context.begin(); q != _context.end(); ++q) { for(p = q->first.begin(); p != q->first.end(); ++p) { h = 5 * h + *p; } for(p = q->second.begin(); p != q->second.end(); ++p) { h = 5 * h + *p; } } } for(p = _facet.begin(); p != _facet.end(); ++p) { h = 5 * h + *p; } h = 5 * h + static_cast(getSecure()); _hashValue = h; _hashInitialized = true; return h; } void IceInternal::Reference::streamWrite(BasicStream* s) const { // // Don't write the identity here. Operations calling streamWrite // write the identity. // // // For compatibility with the old FacetPath. // if(_facet.empty()) { s->write(vector()); } else { vector facetPath; facetPath.push_back(_facet); s->write(facetPath); } s->write(static_cast(_mode)); s->write(getSecure()); // Derived class writes the remainder of the reference. } string IceInternal::Reference::toString() const { string s; // // If the encoded identity string contains characters which // the reference parser uses as separators, then we enclose // the identity string in quotes. // string id = identityToString(_identity); if(id.find_first_of(" \t\n\r:@") != string::npos) { s += "\""; s += id; s += "\""; } else { s += id; } if(!_facet.empty()) { s += " -f "; // // If the encoded facet string contains characters which // the reference parser uses as separators, then we enclose // the facet string in quotes. // string fs = IceUtil::escapeString(_facet, ""); if(fs.find_first_of(" \t\n\r:@") != string::npos) { s += "\""; s += fs; s += "\""; } else { s += fs; } } switch(_mode) { case ModeTwoway: { s += " -t"; break; } case ModeOneway: { s += " -o"; break; } case ModeBatchOneway: { s += " -O"; break; } case ModeDatagram: { s += " -d"; break; } case ModeBatchDatagram: { s += " -D"; break; } } if(getSecure()) { s += " -s"; } return s; // Derived class writes the remainder of the string. } bool IceInternal::Reference::operator==(const Reference& r) const { // // Note: if(this == &r) test is performed by each non-abstract derived class. // if(_mode != r._mode) { return false; } if(_secure != r._secure) { return false; } if(_identity != r._identity) { return false; } if(_hasContext != r._hasContext) { return false; } if(_context != r._context) { return false; } if(_facet != r._facet) { return false; } return true; } bool IceInternal::Reference::operator!=(const Reference& r) const { return !operator==(r); } bool IceInternal::Reference::operator<(const Reference& r) const { // // Note: if(this == &r) test is performed by each non-abstract derived class. // if(_mode < r._mode) { return true; } else if(r._mode < _mode) { return false; } if(!_secure && r._secure) { return true; } else if(r._secure < _secure) { return false; } if(_identity < r._identity) { return true; } else if(r._identity < _identity) { return false; } if(_hasContext < r._hasContext) { return true; } else if(r._hasContext < _hasContext) { return false; } if(_context < r._context) { return true; } else if(r._context < _context) { return false; } if(_facet < r._facet) { return true; } else if(r._facet < _facet) { return false; } return false; } IceInternal::Reference::Reference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, bool sec) : _instance(inst), _communicator(com), _mode(md), _secure(sec), _identity(ident), _hasContext(!ctx.empty()), _context(ctx), _facet(fs), _hashInitialized(false) { } IceInternal::Reference::Reference(const Reference& r) : _instance(r._instance), _communicator(r._communicator), _mode(r._mode), _secure(r._secure), _identity(r._identity), _hasContext(r._hasContext), _context(r._context), _facet(r._facet), _hashInitialized(false) { } void IceInternal::incRef(IceInternal::FixedReference* p) { p->__incRef(); } void IceInternal::decRef(IceInternal::FixedReference* p) { p->__decRef(); } IceInternal::FixedReference::FixedReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, const vector& fixedConns) : Reference(inst, com, ident, ctx, fs, md, false), _fixedConnections(fixedConns) { } const vector& IceInternal::FixedReference::getFixedConnections() const { return _fixedConnections; } vector IceInternal::FixedReference::getEndpoints() const { return vector(); } #ifdef ICEE_HAS_ROUTER ReferencePtr IceInternal::FixedReference::changeRouter(const RouterPrx&) const { return FixedReferencePtr(const_cast(this)); } #endif #ifdef ICEE_HAS_LOCATOR ReferencePtr IceInternal::FixedReference::changeLocator(const LocatorPrx&) const { return FixedReferencePtr(const_cast(this)); } #endif ReferencePtr IceInternal::FixedReference::changeTimeout(int) const { return FixedReferencePtr(const_cast(this)); } void IceInternal::FixedReference::streamWrite(BasicStream* s) const { throw MarshalException(__FILE__, __LINE__, "Cannot marshal a fixed reference"); } string IceInternal::FixedReference::toString() const { throw MarshalException(__FILE__, __LINE__, "Cannot marshal a fixed reference"); } ConnectionPtr IceInternal::FixedReference::getConnection() const { // // Randomize the order of connections. // // If a reference is secure or the mode is datagram or batch // datagram then we throw a NoEndpointException since IceE lacks // this support. // if(getSecure() || getMode() == ModeDatagram || getMode() == ModeBatchDatagram || _fixedConnections.empty() #ifndef ICEE_HAS_BATCH || getMode() == ModeBatchOneway #endif ) { if(_fixedConnections.empty()) { NoEndpointException ex(__FILE__, __LINE__); ex.proxy = toString(); throw ex; } FeatureNotSupportedException ex(__FILE__, __LINE__); if(getSecure()) { ex.unsupportedFeature = "ssl"; } else if(getMode() == ModeDatagram) { ex.unsupportedFeature = "datagram"; } else if(getMode() == ModeBatchDatagram) { ex.unsupportedFeature = "batch datagram"; } #ifndef ICEE_HAS_BATCH else if(getMode() == ModeBatchOneway) { ex.unsupportedFeature = "batch"; } #endif throw ex; } vector randomCons = _fixedConnections; random_shuffle(randomCons.begin(), randomCons.end()); ConnectionPtr connection = randomCons[0]; assert(connection); return connection; } bool IceInternal::FixedReference::operator==(const Reference& r) const { if(this == &r) { return true; } const FixedReference* rhs = dynamic_cast(&r); if(!rhs || !Reference::operator==(r)) { return false; } return _fixedConnections == rhs->_fixedConnections; } bool IceInternal::FixedReference::operator!=(const Reference& r) const { return !operator==(r); } bool IceInternal::FixedReference::operator<(const Reference& r) const { if(this == &r) { return false; } if(Reference::operator<(r)) { return true; } if(Reference::operator==(r)) { const FixedReference* rhs = dynamic_cast(&r); if(rhs) { return _fixedConnections < rhs->_fixedConnections; } } return false; } ReferencePtr IceInternal::FixedReference::clone() const { return new FixedReference(*this); } IceInternal::FixedReference::FixedReference(const FixedReference& r) : Reference(r), _fixedConnections(r._fixedConnections) { } #ifdef ICEE_HAS_ROUTER void IceInternal::incRef(IceInternal::RoutableReference* p) { p->__incRef(); } void IceInternal::decRef(IceInternal::RoutableReference* p) { p->__decRef(); } vector IceInternal::RoutableReference::getRoutedEndpoints() const { if(_routerInfo) { // // If we route, we send everything to the router's client // proxy endpoints. // ObjectPrx clientProxy = _routerInfo->getClientProxy(); return clientProxy->__reference()->getEndpoints(); } return vector(); } ReferencePtr IceInternal::RoutableReference::changeDefault() const { RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(Reference::changeDefault()); r->_routerInfo = getInstance()->routerManager()->get(getInstance()->referenceFactory()->getDefaultRouter()); return r; } ReferencePtr IceInternal::RoutableReference::changeRouter(const RouterPrx& newRouter) const { RouterInfoPtr newRouterInfo = getInstance()->routerManager()->get(newRouter); if(newRouterInfo == _routerInfo) { return RoutableReferencePtr(const_cast(this)); } RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); r->_routerInfo = newRouterInfo; return r; } bool IceInternal::RoutableReference::operator==(const Reference& r) const { // // Note: if(this == &r) test is performed by each non-abstract derived class. // const RoutableReference* rhs = dynamic_cast(&r); if(!rhs || !Reference::operator==(r)) { return false; } return _routerInfo == rhs->_routerInfo; } bool IceInternal::RoutableReference::operator!=(const Reference& r) const { return !operator==(r); } bool IceInternal::RoutableReference::operator<(const Reference& r) const { if(this == &r) { return false; } if(Reference::operator<(r)) { return true; } if(Reference::operator==(r)) { const RoutableReference* rhs = dynamic_cast(&r); if(rhs) { return _routerInfo < rhs->_routerInfo; } } return false; } IceInternal::RoutableReference::RoutableReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, bool sec, const RouterInfoPtr& rtrInfo) : Reference(inst, com, ident, ctx, fs, md, sec), _routerInfo(rtrInfo) { } IceInternal::RoutableReference::RoutableReference(const RoutableReference& r) : Reference(r), _routerInfo(r._routerInfo) { } #endif void IceInternal::incRef(IceInternal::DirectReference* p) { p->__incRef(); } void IceInternal::decRef(IceInternal::DirectReference* p) { p->__decRef(); } #ifdef ICEE_HAS_ROUTER IceInternal::DirectReference::DirectReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, bool sec, const vector& endpts, const RouterInfoPtr& rtrInfo) : RoutableReference(inst, com, ident, ctx, fs, md, sec, rtrInfo), _endpoints(endpts) { } #else IceInternal::DirectReference::DirectReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, bool sec, const vector& endpts) : Reference(inst, com, ident, ctx, fs, md, sec), _endpoints(endpts) { } #endif vector IceInternal::DirectReference::getEndpoints() const { return _endpoints; } DirectReferencePtr IceInternal::DirectReference::changeEndpoints(const vector& newEndpoints) const { if(newEndpoints == _endpoints) { return DirectReferencePtr(const_cast(this)); } DirectReferencePtr r = DirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); r->_endpoints = newEndpoints; return r; } ReferencePtr IceInternal::DirectReference::changeDefault() const { // // Return an indirect reference if a default locator is set. // #ifdef ICEE_HAS_LOCATOR LocatorPrx loc = getInstance()->referenceFactory()->getDefaultLocator(); if(loc) { LocatorInfoPtr newLocatorInfo = getInstance()->locatorManager()->get(loc); #ifdef ICEE_HAS_ROUTER return getInstance()->referenceFactory()->create(getIdentity(), Context(), "", ModeTwoway, false, "", 0, newLocatorInfo); #else return getInstance()->referenceFactory()->create(getIdentity(), Context(), "", ModeTwoway, false, "", newLocatorInfo); #endif } else #endif // ICEE_HAS_LOCATOR { return Parent::changeDefault(); } } #ifdef ICEE_HAS_LOCATOR ReferencePtr IceInternal::DirectReference::changeLocator(const LocatorPrx& newLocator) const { if(newLocator) { LocatorInfoPtr newLocatorInfo = getInstance()->locatorManager()->get(newLocator); #ifdef ICEE_HAS_ROUTER return getInstance()->referenceFactory()->create(getIdentity(), getContext(), getFacet(), getMode(), getSecure(), "", 0, newLocatorInfo); #else return getInstance()->referenceFactory()->create(getIdentity(), getContext(), getFacet(), getMode(), getSecure(), "", newLocatorInfo); #endif } else { return DirectReferencePtr(const_cast(this)); } } #endif ReferencePtr IceInternal::DirectReference::changeTimeout(int newTimeout) const { DirectReferencePtr r = DirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); vector newEndpoints; vector::const_iterator p; for(p = _endpoints.begin(); p != _endpoints.end(); ++p) { newEndpoints.push_back((*p)->timeout(newTimeout)); } r->_endpoints = newEndpoints; return r; } void IceInternal::DirectReference::streamWrite(BasicStream* s) const { Parent::streamWrite(s); Int sz = static_cast(_endpoints.size()); s->writeSize(sz); if(sz) { for(vector::const_iterator p = _endpoints.begin(); p != _endpoints.end(); ++p) { (*p)->streamWrite(s); } } else { s->write(string("")); // Adapter id. } } string IceInternal::DirectReference::toString() const { string result = Parent::toString(); vector::const_iterator p; for(p = _endpoints.begin(); p != _endpoints.end(); ++p) { string endp = (*p)->toString(); if(!endp.empty()) { result.append(":"); result.append(endp); } } return result; } ConnectionPtr IceInternal::DirectReference::getConnection() const { #ifdef ICEE_HAS_ROUTER vector endpts = Parent::getRoutedEndpoints(); if(endpts.empty()) { endpts = _endpoints; } #else vector endpts = _endpoints; #endif vector filteredEndpoints = filterEndpoints(endpts, getMode(), getSecure()); if(filteredEndpoints.empty()) { NoEndpointException ex(__FILE__, __LINE__); ex.proxy = toString(); throw ex; } OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); ConnectionPtr connection = factory->create(filteredEndpoints); assert(connection); #if defined(ICEE_HAS_ROUTER) && !defined(ICEE_PURE_CLIENT) // // If we have a router, set the object adapter for this router // (if any) to the new connection, so that callbacks from the // router can be received over this new connection. // if(getRouterInfo()) { connection->setAdapter(getRouterInfo()->getAdapter()); } #endif return connection; } bool IceInternal::DirectReference::operator==(const Reference& r) const { if(this == &r) { return true; } const DirectReference* rhs = dynamic_cast(&r); if(!rhs || !Parent::operator==(r)) { return false; } return _endpoints == rhs->_endpoints; } bool IceInternal::DirectReference::operator!=(const Reference& r) const { return !operator==(r); } bool IceInternal::DirectReference::operator<(const Reference& r) const { if(this == &r) { return false; } if(Parent::operator<(r)) { return true; } if(Parent::operator==(r)) { const DirectReference* rhs = dynamic_cast(&r); if(rhs) { return _endpoints < rhs->_endpoints; } } return false; } ReferencePtr IceInternal::DirectReference::clone() const { return new DirectReference(*this); } IceInternal::DirectReference::DirectReference(const DirectReference& r) : Parent(r), _endpoints(r._endpoints) { } #ifdef ICEE_HAS_LOCATOR void IceInternal::incRef(IceInternal::IndirectReference* p) { p->__incRef(); } void IceInternal::decRef(IceInternal::IndirectReference* p) { p->__decRef(); } #ifdef ICEE_HAS_ROUTER IceInternal::IndirectReference::IndirectReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, bool sec, const string& adptid, const RouterInfoPtr& rtrInfo, const LocatorInfoPtr& locInfo) : RoutableReference(inst, com ident, ctx, fs, md, sec, rtrInfo), _adapterId(adptid), _locatorInfo(locInfo) { } #else IceInternal::IndirectReference::IndirectReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, bool sec, const string& adptid, const LocatorInfoPtr& locInfo) : Reference(inst, com, ident, ctx, fs, md, sec), _adapterId(adptid), _locatorInfo(locInfo) { } #endif vector IceInternal::IndirectReference::getEndpoints() const { return vector(); } ReferencePtr IceInternal::IndirectReference::changeDefault() const { // // Return a direct reference if no default locator is defined. // LocatorPrx loc = getInstance()->referenceFactory()->getDefaultLocator(); if(!loc) { #ifdef ICEE_HAS_ROUTER return getInstance()->referenceFactory()->create(getIdentity(), Context(), "", ModeTwoway, false, vector(), getRouterInfo()); #else return getInstance()->referenceFactory()->create(getIdentity(), Context(), "", ModeTwoway, false, vector()); #endif } else { IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(Parent::changeDefault()); r->_locatorInfo = getInstance()->locatorManager()->get(loc); return r; } } ReferencePtr IceInternal::IndirectReference::changeLocator(const LocatorPrx& newLocator) const { // // Return a direct reference if a null locator is given. // if(!newLocator) { #ifdef ICEE_HAS_ROUTER return getInstance()->referenceFactory()->create(getIdentity(), getContext(), getFacet(), getMode(), getSecure(), vector(), getRouterInfo()); #else return getInstance()->referenceFactory()->create(getIdentity(), getContext(), getFacet(), getMode(), getSecure(), vector()); #endif } else { LocatorInfoPtr newLocatorInfo = getInstance()->locatorManager()->get(newLocator); if(newLocatorInfo == _locatorInfo) { return IndirectReferencePtr(const_cast(this)); } IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); r->_locatorInfo = newLocatorInfo; return r; } } ReferencePtr IceInternal::IndirectReference::changeTimeout(int newTimeout) const { IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); if(_locatorInfo) { LocatorPrx newLocator = LocatorPrx::uncheckedCast(_locatorInfo->getLocator()->ice_timeout(newTimeout)); r->_locatorInfo = getInstance()->locatorManager()->get(newLocator); } return r; } void IceInternal::IndirectReference::streamWrite(BasicStream* s) const { Parent::streamWrite(s); s->writeSize(0); s->write(_adapterId); } string IceInternal::IndirectReference::toString() const { string result = Parent::toString(); if(_adapterId.empty()) { return result; } result.append(" @ "); // // If the encoded adapter id string contains characters which the // reference parser uses as separators, then we enclose the // adapter id string in quotes. // string a = IceUtil::escapeString(_adapterId, ""); if(a.find_first_of(" \t\n\r") != string::npos) { result.append("\""); result.append(a); result.append("\""); } else { result.append(_adapterId); } return result; } ConnectionPtr IceInternal::IndirectReference::getConnection() const { ConnectionPtr connection; while(true) { #ifdef ICEE_HAS_ROUTER vector endpts = Parent::getRoutedEndpoints(); #else vector endpts; #endif bool cached = false; if(endpts.empty() && _locatorInfo) { const IndirectReferencePtr self = const_cast(this); endpts = _locatorInfo->getEndpoints(self, cached); } vector filteredEndpoints = filterEndpoints(endpts, getMode(), getSecure()); if(filteredEndpoints.empty()) { NoEndpointException ex(__FILE__, __LINE__); ex.proxy = toString(); throw ex; } try { OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); connection = factory->create(filteredEndpoints); assert(connection); } catch(const LocalException& ex) { #ifdef ICEE_HAS_ROUTER if(!getRouterInfo()) #endif { assert(_locatorInfo); const IndirectReferencePtr self = const_cast(this); _locatorInfo->clearCache(self); if(cached) { TraceLevelsPtr traceLevels = getInstance()->traceLevels(); LoggerPtr logger = getInstance()->logger(); if(traceLevels->retry >= 2) { Trace out(logger, traceLevels->retryCat); out << "connection to cached endpoints failed\n" << "removing endpoints from cache and trying one more time\n" << ex.toString(); } continue; } } throw; } break; } #if defined(ICEE_HAS_ROUTER) && !defined(ICEE_PURE_CLIENT) // // If we have a router, set the object adapter for this router // (if any) to the new connection, so that callbacks from the // router can be received over this new connection. // if(getRouterInfo()) { connection->setAdapter(getRouterInfo()->getAdapter()); } #endif assert(connection); return connection; } bool IceInternal::IndirectReference::operator==(const Reference& r) const { if(this == &r) { return true; } const IndirectReference* rhs = dynamic_cast(&r); if(!rhs || !Parent::operator==(r)) { return false; } return _adapterId == rhs->_adapterId && _locatorInfo == rhs->_locatorInfo; } bool IceInternal::IndirectReference::operator!=(const Reference& r) const { return !operator==(r); } bool IceInternal::IndirectReference::operator<(const Reference& r) const { if(this == &r) { return false; } if(Parent::operator<(r)) { return true; } if(Parent::operator==(r)) { const IndirectReference* rhs = dynamic_cast(&r); if(rhs) { if(_adapterId < rhs->_adapterId) { return true; } else if(rhs->_adapterId < _adapterId) { return false; } return _locatorInfo < rhs->_locatorInfo; } } return false; } ReferencePtr IceInternal::IndirectReference::clone() const { return new IndirectReference(*this); } IceInternal::IndirectReference::IndirectReference(const IndirectReference& r) : Parent(r), _adapterId(r._adapterId), _locatorInfo(r._locatorInfo) { } #endif // ICEE_HAS_LOCATOR vector IceInternal::filterEndpoints(const vector& allEndpoints, Reference::Mode m, bool sec) { vector endpoints; // // If a secure endpoint, batch (if batch is not supported), // datagram or batch datagram endpoint is requested since IceE // lacks this support we throw an unsupported feature. // if(sec || m == Reference::ModeDatagram || m == Reference::ModeBatchDatagram #ifndef ICEE_HAS_BATCH || m == Reference::ModeBatchOneway #endif ) { FeatureNotSupportedException ex(__FILE__, __LINE__); if(sec) { ex.unsupportedFeature = "ssl"; } else if(m == Reference::ModeDatagram) { ex.unsupportedFeature = "datagram"; } else if(m == Reference::ModeBatchDatagram) { ex.unsupportedFeature = "batch datagram"; } #ifndef ICEE_HAS_BATCH else if(m == Reference::ModeBatchOneway) { ex.unsupportedFeature = "batch"; } #endif throw ex; } endpoints = allEndpoints; // // Filter out unknown endpoints. // endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), Ice::constMemFun(&Endpoint::unknown)), endpoints.end()); // // Randomize the order of endpoints. // random_shuffle(endpoints.begin(), endpoints.end()); return endpoints; }