diff options
author | Michi Henning <michi@zeroc.com> | 2004-10-29 04:21:38 +0000 |
---|---|---|
committer | Michi Henning <michi@zeroc.com> | 2004-10-29 04:21:38 +0000 |
commit | 1a469c19cd810f7d60e45f2a1726372455dde834 (patch) | |
tree | 7289e8a4d55672971d06682ea05747227b79af06 /cpp/src | |
parent | Added try-catch block to Generate.cs. Updated version number to 2.0.0. (diff) | |
download | ice-1a469c19cd810f7d60e45f2a1726372455dde834.tar.bz2 ice-1a469c19cd810f7d60e45f2a1726372455dde834.tar.xz ice-1a469c19cd810f7d60e45f2a1726372455dde834.zip |
Reference refactoring.
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/ConnectionFactory.cpp | 3 | ||||
-rw-r--r-- | cpp/src/Ice/ConnectionI.cpp | 3 | ||||
-rw-r--r-- | cpp/src/Ice/FactoryTable.cpp | 2 | ||||
-rw-r--r-- | cpp/src/Ice/FactoryTableDef.cpp | 2 | ||||
-rw-r--r-- | cpp/src/Ice/LocatorInfo.cpp | 108 | ||||
-rw-r--r-- | cpp/src/Ice/LocatorInfo.h | 6 | ||||
-rw-r--r-- | cpp/src/Ice/ObjectAdapterI.cpp | 36 | ||||
-rw-r--r-- | cpp/src/Ice/Outgoing.cpp | 18 | ||||
-rw-r--r-- | cpp/src/Ice/OutgoingAsync.cpp | 41 | ||||
-rw-r--r-- | cpp/src/Ice/Proxy.cpp | 67 | ||||
-rw-r--r-- | cpp/src/Ice/ProxyFactory.cpp | 2 | ||||
-rw-r--r-- | cpp/src/Ice/Reference.cpp | 1364 | ||||
-rw-r--r-- | cpp/src/Ice/Reference.h | 263 | ||||
-rw-r--r-- | cpp/src/Ice/ReferenceFactory.cpp | 206 | ||||
-rw-r--r-- | cpp/src/Ice/ReferenceFactory.h | 36 |
15 files changed, 1348 insertions, 809 deletions
diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp index c1626d39ea7..21f64d94500 100644 --- a/cpp/src/Ice/ConnectionFactory.cpp +++ b/cpp/src/Ice/ConnectionFactory.cpp @@ -380,8 +380,9 @@ IceInternal::OutgoingConnectionFactory::setRouter(const RouterPrx& router) // ObjectPrx proxy = routerInfo->getClientProxy(); ObjectAdapterPtr adapter = routerInfo->getAdapter(); + vector<EndpointPtr> endpoints = proxy->__reference()->getEndpoints(); vector<EndpointPtr>::const_iterator p; - for(p = proxy->__reference()->endpoints.begin(); p != proxy->__reference()->endpoints.end(); ++p) + for(p = endpoints.begin(); p != endpoints.end(); ++p) { EndpointPtr endpoint = *p; diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp index 5ce17509421..002041cb492 100644 --- a/cpp/src/Ice/ConnectionI.cpp +++ b/cpp/src/Ice/ConnectionI.cpp @@ -1092,11 +1092,10 @@ Ice::ConnectionI::createProxy(const Identity& ident) const // Create a reference and return a reverse proxy for this // reference. // - vector<EndpointPtr> endpoints; vector<ConnectionIPtr> connections; connections.push_back(const_cast<ConnectionI*>(this)); ReferencePtr ref = _instance->referenceFactory()->create(ident, Context(), "", Reference::ModeTwoway, - false, "", endpoints, 0, 0, connections, true); + false, true, connections); return _instance->proxyFactory()->referenceToProxy(ref); } diff --git a/cpp/src/Ice/FactoryTable.cpp b/cpp/src/Ice/FactoryTable.cpp index b0f288517ae..bbb6c9aa864 100644 --- a/cpp/src/Ice/FactoryTable.cpp +++ b/cpp/src/Ice/FactoryTable.cpp @@ -7,7 +7,7 @@ // // ********************************************************************** -#include <Ice/FactoryTable.h>
+#include <Ice/FactoryTable.h> #include <Ice/UserExceptionFactory.h> // diff --git a/cpp/src/Ice/FactoryTableDef.cpp b/cpp/src/Ice/FactoryTableDef.cpp index 2415b1af983..a15f40f8b9d 100644 --- a/cpp/src/Ice/FactoryTableDef.cpp +++ b/cpp/src/Ice/FactoryTableDef.cpp @@ -79,7 +79,7 @@ Ice::FactoryTableDef::getExceptionFactory(const std::string& t) const // // Remove a factory from the exception factory table. If the factory // is not present, do nothing; otherwise, decrement the factory's -// reference count if the count drops to zero, remove the factory's +// reference count; if the count drops to zero, remove the factory's // entry from the table. // void diff --git a/cpp/src/Ice/LocatorInfo.cpp b/cpp/src/Ice/LocatorInfo.cpp index ab23e8f9995..de67616c93a 100644 --- a/cpp/src/Ice/LocatorInfo.cpp +++ b/cpp/src/Ice/LocatorInfo.cpp @@ -270,58 +270,58 @@ IceInternal::LocatorInfo::getLocatorRegistry() } vector<EndpointPtr> -IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, bool& cached) +IceInternal::LocatorInfo::getEndpoints(const IndirectReferencePtr& ref, bool& cached) { - assert(ref->endpoints.empty()); - vector<EndpointPtr> endpoints; ObjectPrx object; cached = true; try { - if(!ref->adapterId.empty()) + if(!ref->getAdapterId().empty()) { - if(!_table->getAdapterEndpoints(ref->adapterId, endpoints)) + if(!_table->getAdapterEndpoints(ref->getAdapterId(), endpoints)) { cached = false; - object = _locator->findAdapterById(ref->adapterId); + object = _locator->findAdapterById(ref->getAdapterId()); if(object) { - endpoints = object->__reference()->endpoints; - - if(!endpoints.empty()) - { - _table->addAdapterEndpoints(ref->adapterId, endpoints); - } + endpoints = object->__reference()->getEndpoints(); + _table->addAdapterEndpoints(ref->getAdapterId(), endpoints); } } } else { - if(!_table->getProxy(ref->identity, object)) + if(!_table->getProxy(ref->getIdentity(), object)) { cached = false; - object = _locator->findObjectById(ref->identity); + object = _locator->findObjectById(ref->getIdentity()); } if(object) { - if(!object->__reference()->endpoints.empty()) + DirectReferencePtr odr = DirectReferencePtr::dynamicCast(object->__reference()); + if(odr) { - endpoints = object->__reference()->endpoints; + endpoints = odr->getEndpoints(); } - else if(!object->__reference()->adapterId.empty()) + else { - endpoints = getEndpoints(object->__reference(), cached); + IndirectReferencePtr oir = IndirectReferencePtr::dynamicCast(object->__reference()); + assert(oir); + if(!oir->getAdapterId().empty()) + { + endpoints = getEndpoints(oir, cached); + } } } if(!cached && !endpoints.empty()) { - _table->addProxy(ref->identity, object); + _table->addProxy(ref->getIdentity(), object); } } } @@ -329,14 +329,14 @@ IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, bool& cached) { NotRegisteredException ex(__FILE__, __LINE__); ex.kindOfObject = "object adapter"; - ex.id = ref->adapterId; + ex.id = ref->getAdapterId(); throw ex; } catch(const ObjectNotFoundException&) { NotRegisteredException ex(__FILE__, __LINE__); ex.kindOfObject = "object"; - ex.id = identityToString(ref->identity); + ex.id = identityToString(ref->getIdentity()); throw ex; } catch(const NotRegisteredException&) @@ -345,23 +345,24 @@ IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, bool& cached) } catch(const LocalException& ex) { - if(ref->instance->traceLevels()->location >= 1) + if(ref->getInstance()->traceLevels()->location >= 1) { - Trace out(ref->instance->logger(), ref->instance->traceLevels()->locationCat); + Trace out(ref->getInstance()->logger(), ref->getInstance()->traceLevels()->locationCat); out << "couldn't contact the locator to retrieve adapter endpoints\n"; - if(ref->adapterId.empty()) + if(!ref) { - out << "object = " << identityToString(ref->identity) << "\n"; + out << "object = " << identityToString(ref->getIdentity()) << "\n"; } else { - out << "adapter = " << ref->adapterId << "\n"; + out << "adapter = " << ref->getAdapterId() << "\n"; } out << "reason = " << ex; } + throw; } - if(ref->instance->traceLevels()->location >= 1 && !endpoints.empty()) + if(ref->getInstance()->traceLevels()->location >= 1 && !endpoints.empty()) { if(cached) { @@ -377,45 +378,57 @@ IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, bool& cached) } void -IceInternal::LocatorInfo::clearObjectCache(const ReferencePtr& ref) +IceInternal::LocatorInfo::clearObjectCache(const IndirectReferencePtr& ref) { - if(ref->adapterId.empty() && ref->endpoints.empty()) + if(ref->getAdapterId().empty()) { - ObjectPrx object = _table->removeProxy(ref->identity); + ObjectPrx object = _table->removeProxy(ref->getIdentity()); - if(ref->instance->traceLevels()->location >= 2 && object && !object->__reference()->endpoints.empty()) + if(ref->getInstance()->traceLevels()->location >= 2 && object) { - trace("removed endpoints from locator table", ref, object->__reference()->endpoints); + vector<EndpointPtr> endpoints = object->__reference()->getEndpoints(); + if(!endpoints.empty()) + { + trace("removed endpoints from locator table", ref, endpoints); + } } } } void -IceInternal::LocatorInfo::clearCache(const ReferencePtr& ref) +IceInternal::LocatorInfo::clearCache(const IndirectReferencePtr& ref) { - if(!ref->adapterId.empty()) + if(!ref->getAdapterId().empty()) { - vector<EndpointPtr> endpoints = _table->removeAdapterEndpoints(ref->adapterId); + vector<EndpointPtr> endpoints = _table->removeAdapterEndpoints(ref->getAdapterId()); - if(!endpoints.empty() && ref->instance->traceLevels()->location >= 2) + if(!endpoints.empty() && ref->getInstance()->traceLevels()->location >= 2) { trace("removed endpoints from locator table", ref, endpoints); } } - else if(ref->endpoints.empty()) + else { - ObjectPrx object = _table->removeProxy(ref->identity); + ObjectPrx object = _table->removeProxy(ref->getIdentity()); if(object) { - if(!object->__reference()->adapterId.empty()) + IndirectReferencePtr oir = IndirectReferencePtr::dynamicCast(object->__reference()); + if(oir) { - clearCache(object->__reference()); + if(!oir->getAdapterId().empty()) + { + IndirectReferencePtr ir = IndirectReferencePtr::dynamicCast(object->__reference()); + if(ir) + { + clearCache(ir); + } + } } - else if(!object->__reference()->endpoints.empty()) + else { - if(ref->instance->traceLevels()->location >= 2) + if(ref->getInstance()->traceLevels()->location >= 2) { - trace("removed endpoints from locator table", ref, object->__reference()->endpoints); + trace("removed endpoints from locator table", ref, object->__reference()->getEndpoints()); } } } @@ -425,15 +438,16 @@ IceInternal::LocatorInfo::clearCache(const ReferencePtr& ref) void IceInternal::LocatorInfo::trace(const string& msg, const ReferencePtr& ref, const vector<EndpointPtr>& endpoints) { - Trace out(ref->instance->logger(), ref->instance->traceLevels()->locationCat); + Trace out(ref->getInstance()->logger(), ref->getInstance()->traceLevels()->locationCat); out << msg << '\n'; - if(ref->adapterId.empty()) + IndirectReferencePtr ir = IndirectReferencePtr::dynamicCast(ref); + if(!ir) { - out << "object = " << identityToString(ref->identity) << '\n'; + out << "object = " << identityToString(ref->getIdentity()) << '\n'; } else { - out << "adapter = " << ref->adapterId << '\n'; + out << "adapter = " << ir->getAdapterId() << '\n'; } const char* sep = endpoints.size() > 1 ? ":" : ""; diff --git a/cpp/src/Ice/LocatorInfo.h b/cpp/src/Ice/LocatorInfo.h index 09dbaa75b7c..4e00edae33f 100644 --- a/cpp/src/Ice/LocatorInfo.h +++ b/cpp/src/Ice/LocatorInfo.h @@ -79,9 +79,9 @@ public: Ice::LocatorPrx getLocator() const; Ice::LocatorRegistryPrx getLocatorRegistry(); - std::vector<EndpointPtr> getEndpoints(const ReferencePtr&, bool&); - void clearCache(const ReferencePtr&); - void clearObjectCache(const ReferencePtr&); + std::vector<EndpointPtr> getEndpoints(const IndirectReferencePtr&, bool&); + void clearCache(const IndirectReferencePtr&); + void clearObjectCache(const IndirectReferencePtr&); private: diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp index a17b0abd51e..72220d29182 100644 --- a/cpp/src/Ice/ObjectAdapterI.cpp +++ b/cpp/src/Ice/ObjectAdapterI.cpp @@ -397,7 +397,7 @@ Ice::ObjectAdapterI::findByProxy(const ObjectPrx& proxy) const checkForDeactivation(); ReferencePtr ref = proxy->__reference(); - return findFacet(ref->identity, ref->facet); + return findFacet(ref->getIdentity(), ref->getFacet()); } void @@ -467,7 +467,7 @@ Ice::ObjectAdapterI::createReverseProxy(const Identity& ident) const // vector<EndpointPtr> endpoints; ReferencePtr ref = _instance->referenceFactory()->create(ident, Context(), "", Reference::ModeTwoway, - false, "", endpoints, 0, 0, connections, true); + false, true, connections); return _instance->proxyFactory()->referenceToProxy(ref); } @@ -486,8 +486,8 @@ Ice::ObjectAdapterI::addRouter(const RouterPrx& router) // adapter. // ObjectPrx proxy = routerInfo->getServerProxy(); - copy(proxy->__reference()->endpoints.begin(), proxy->__reference()->endpoints.end(), - back_inserter(_routerEndpoints)); + vector<EndpointPtr> endpoints = proxy->__reference()->getEndpoints(); + copy(endpoints.begin(), endpoints.end(), back_inserter(_routerEndpoints)); sort(_routerEndpoints.begin(), _routerEndpoints.end()); // Must be sorted. _routerEndpoints.erase(unique(_routerEndpoints.begin(), _routerEndpoints.end()), _routerEndpoints.end()); @@ -546,13 +546,18 @@ Ice::ObjectAdapterI::isLocal(const ObjectPrx& proxy) const ReferencePtr ref = proxy->__reference(); vector<EndpointPtr>::const_iterator p; - if(!ref->adapterId.empty()) + IndirectReferencePtr ir = IndirectReferencePtr::dynamicCast(ref); + if(ir) { - // - // Proxy is local if the reference adapter id matches this - // adapter id. - // - return ref->adapterId == _id; + if(!ir->getAdapterId().empty()) + { + // + // Proxy is local if the reference adapter id matches this + // adapter id. + // + return ir->getAdapterId() == _id; + } + return false; } // @@ -560,7 +565,8 @@ Ice::ObjectAdapterI::isLocal(const ObjectPrx& proxy) const // endpoints used by this object adapter's incoming connection // factories are considered local. // - for(p = ref->endpoints.begin(); p != ref->endpoints.end(); ++p) + vector<EndpointPtr> endpoints = ref->getEndpoints(); + for(p = endpoints.begin(); p != endpoints.end(); ++p) { vector<IncomingConnectionFactoryPtr>::const_iterator q; for(q = _incomingConnectionFactories.begin(); q != _incomingConnectionFactories.end(); ++q) @@ -577,7 +583,7 @@ Ice::ObjectAdapterI::isLocal(const ObjectPrx& proxy) const // router's server proxy endpoints (if any), are also considered // local. // - for(p = ref->endpoints.begin(); p != ref->endpoints.end(); ++p) + for(p = endpoints.begin(); p != endpoints.end(); ++p) { if(binary_search(_routerEndpoints.begin(), _routerEndpoints.end(), *p)) // _routerEndpoints is sorted. { @@ -788,8 +794,7 @@ Ice::ObjectAdapterI::newProxy(const Identity& ident) const vector<EndpointPtr> endpoints; ReferencePtr ref = _instance->referenceFactory()->create(ident, Context(), "", Reference::ModeTwoway, false, _id, - endpoints, 0, _locatorInfo, - vector<ConnectionIPtr>(), true); + 0, _locatorInfo, true); // // Return a proxy for the reference. @@ -821,8 +826,7 @@ Ice::ObjectAdapterI::newDirectProxy(const Identity& ident) const // Create a reference and return a proxy for this reference. // ReferencePtr ref = _instance->referenceFactory()->create(ident, Context(), "", Reference::ModeTwoway, - false, "", endpoints, 0, _locatorInfo, - vector<ConnectionIPtr>(), true); + false, endpoints, 0, true); return _instance->proxyFactory()->referenceToProxy(ref); } diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp index e289f1c74c7..b73438a2717 100644 --- a/cpp/src/Ice/Outgoing.cpp +++ b/cpp/src/Ice/Outgoing.cpp @@ -49,11 +49,11 @@ IceInternal::Outgoing::Outgoing(ConnectionI* connection, Reference* ref, const s _connection(connection), _reference(ref), _state(StateUnsent), - _is(ref->instance.get()), - _os(ref->instance.get()), + _is(ref->getInstance().get()), + _os(ref->getInstance().get()), _compress(compress) { - switch(_reference->mode) + switch(_reference->getMode()) { case Reference::ModeTwoway: case Reference::ModeOneway: @@ -71,19 +71,19 @@ IceInternal::Outgoing::Outgoing(ConnectionI* connection, Reference* ref, const s } } - _reference->identity.__write(&_os); + _reference->getIdentity().__write(&_os); // // For compatibility with the old FacetPath. // - if(_reference->facet.empty()) + if(_reference->getFacet().empty()) { _os.write(vector<string>()); } else { vector<string> facetPath; - facetPath.push_back(_reference->facet); + facetPath.push_back(_reference->getFacet()); _os.write(facetPath); } @@ -112,7 +112,7 @@ IceInternal::Outgoing::invoke() { _os.endWriteEncaps(); - switch(_reference->mode) + switch(_reference->getMode()) { case Reference::ModeTwoway: { @@ -256,7 +256,7 @@ IceInternal::Outgoing::finished(BasicStream& is) { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - assert(_reference->mode == Reference::ModeTwoway); // Can only be called for twoways. + assert(_reference->getMode() == Reference::ModeTwoway); // Can only be called for twoways. assert(_state <= StateInProgress); @@ -422,7 +422,7 @@ IceInternal::Outgoing::finished(const LocalException& ex) { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - assert(_reference->mode == Reference::ModeTwoway); // Can only be called for twoways. + assert(_reference->getMode() == Reference::ModeTwoway); // Can only be called for twoways. assert(_state <= StateInProgress); diff --git a/cpp/src/Ice/OutgoingAsync.cpp b/cpp/src/Ice/OutgoingAsync.cpp index 3b8cb69361c..ef4258000d5 100644 --- a/cpp/src/Ice/OutgoingAsync.cpp +++ b/cpp/src/Ice/OutgoingAsync.cpp @@ -204,9 +204,10 @@ IceInternal::OutgoingAsync::__finished(const LocalException& exc) if(_reference) { - if(_reference->locatorInfo) + IndirectReferencePtr ir = IndirectReferencePtr::dynamicCast(_reference); + if(ir && ir->getLocatorInfo()) { - _reference->locatorInfo->clearObjectCache(_reference); + ir->getLocatorInfo()->clearObjectCache(ir); } bool doRetry = false; @@ -224,7 +225,7 @@ IceInternal::OutgoingAsync::__finished(const LocalException& exc) { try { - ProxyFactoryPtr proxyFactory = _reference->instance->proxyFactory(); + ProxyFactoryPtr proxyFactory = _reference->getInstance()->proxyFactory(); if(proxyFactory) { proxyFactory->checkRetryAfterException(exc, _cnt); @@ -291,33 +292,34 @@ IceInternal::OutgoingAsync::__prepare(const ObjectPrx& prx, const string& operat _cnt = 0; _mode = mode; assert(!__is); - __is = new BasicStream(_reference->instance.get()); + __is = new BasicStream(_reference->getInstance().get()); assert(!__os); - __os = new BasicStream(_reference->instance.get()); + __os = new BasicStream(_reference->getInstance().get()); // // If we are using a router, then add the proxy to the router info object. // - if(_reference->routerInfo) + RoutableReferencePtr rr = RoutableReferencePtr::dynamicCast(_reference); + if(rr && rr->getRouterInfo()) { - _reference->routerInfo->addProxy(prx); + rr->getRouterInfo()->addProxy(prx); } _connection->prepareRequest(__os); - _reference->identity.__write(__os); + _reference->getIdentity().__write(__os); // // For compatibility with the old FacetPath. // - if(_reference->facet.empty()) + if(_reference->getFacet().empty()) { __os->write(vector<string>()); } else { vector<string> facetPath; - facetPath.push_back(_reference->facet); + facetPath.push_back(_reference->getFacet()); __os->write(facetPath); } @@ -371,12 +373,13 @@ IceInternal::OutgoingAsync::__send() } catch(const LocalException& ex) { - if(_reference->locatorInfo) + IndirectReferencePtr ir = IndirectReferencePtr::dynamicCast(_reference); + if(ir && ir->getLocatorInfo()) { - _reference->locatorInfo->clearObjectCache(_reference); + ir->getLocatorInfo()->clearObjectCache(ir); } - ProxyFactoryPtr proxyFactory = _reference->instance->proxyFactory(); + ProxyFactoryPtr proxyFactory = _reference->getInstance()->proxyFactory(); if(proxyFactory) { proxyFactory->checkRetryAfterException(ex, _cnt); @@ -401,9 +404,9 @@ IceInternal::OutgoingAsync::warning(const Exception& ex) const { if(_reference) // Don't print anything if cleanup() was already called. { - if(_reference->instance->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) + if(_reference->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) { - Warning out(_reference->instance->logger()); + Warning out(_reference->getInstance()->logger()); out << "Ice::Exception raised by AMI callback:\n" << ex; } } @@ -414,9 +417,9 @@ IceInternal::OutgoingAsync::warning(const std::exception& ex) const { if(_reference) // Don't print anything if cleanup() was already called. { - if(_reference->instance->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) + if(_reference->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) { - Warning out(_reference->instance->logger()); + Warning out(_reference->getInstance()->logger()); out << "std::exception raised by AMI callback:\n" << ex.what(); } } @@ -427,9 +430,9 @@ IceInternal::OutgoingAsync::warning() const { if(_reference) // Don't print anything if cleanup() was already called. { - if(_reference->instance->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) + if(_reference->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) { - Warning out(_reference->instance->logger()); + Warning out(_reference->getInstance()->logger()); out << "unknown exception raised by AMI callback"; } } diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp index 99fdf23b5d4..7b7a4095ad9 100644 --- a/cpp/src/Ice/Proxy.cpp +++ b/cpp/src/Ice/Proxy.cpp @@ -97,13 +97,13 @@ IceProxy::Ice::Object::operator<(const Object& r) const Int IceProxy::Ice::Object::ice_hash() const { - return _reference->hashValue; + return _reference->hash(); } bool IceProxy::Ice::Object::ice_isA(const string& __id) { - return ice_isA(__id, _reference->context); + return ice_isA(__id, _reference->getContext()); } bool @@ -132,7 +132,7 @@ IceProxy::Ice::Object::ice_isA(const string& __id, const Context& __context) void IceProxy::Ice::Object::ice_ping() { - ice_ping(_reference->context); + ice_ping(_reference->getContext()); } void @@ -161,7 +161,7 @@ IceProxy::Ice::Object::ice_ping(const Context& __context) vector<string> IceProxy::Ice::Object::ice_ids() { - return ice_ids(_reference->context); + return ice_ids(_reference->getContext()); } vector<string> @@ -190,7 +190,7 @@ IceProxy::Ice::Object::ice_ids(const Context& __context) string IceProxy::Ice::Object::ice_id() { - return ice_id(_reference->context); + return ice_id(_reference->getContext()); } string @@ -222,7 +222,7 @@ IceProxy::Ice::Object::ice_invoke(const string& operation, const vector<Byte>& inParams, vector<Byte>& outParams) { - return ice_invoke(operation, mode, inParams, outParams, _reference->context); + return ice_invoke(operation, mode, inParams, outParams, _reference->getContext()); } bool @@ -265,7 +265,7 @@ IceProxy::Ice::Object::ice_invoke_async(const AMI_Object_ice_invokePtr& cb, OperationMode mode, const vector<Byte>& inParams) { - ice_invoke_async(cb, operation, mode, inParams, _reference->context); + ice_invoke_async(cb, operation, mode, inParams, _reference->getContext()); } void @@ -282,13 +282,13 @@ IceProxy::Ice::Object::ice_invoke_async(const AMI_Object_ice_invokePtr& cb, Context IceProxy::Ice::Object::ice_getContext() const { - return _reference->context; + return _reference->getContext(); } ObjectPrx IceProxy::Ice::Object::ice_newContext(const Context& newContext) const { - if(newContext == _reference->context) + if(newContext == _reference->getContext()) { return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); } @@ -303,13 +303,13 @@ IceProxy::Ice::Object::ice_newContext(const Context& newContext) const Identity IceProxy::Ice::Object::ice_getIdentity() const { - return _reference->identity; + return _reference->getIdentity(); } ObjectPrx IceProxy::Ice::Object::ice_newIdentity(const Identity& newIdentity) const { - if(newIdentity == _reference->identity) + if(newIdentity == _reference->getIdentity()) { return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); } @@ -324,13 +324,13 @@ IceProxy::Ice::Object::ice_newIdentity(const Identity& newIdentity) const const string& IceProxy::Ice::Object::ice_getFacet() const { - return _reference->facet; + return _reference->getFacet(); } ObjectPrx IceProxy::Ice::Object::ice_newFacet(const string& newFacet) const { - if(newFacet == _reference->facet) + if(newFacet == _reference->getFacet()) { return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); } @@ -361,7 +361,7 @@ IceProxy::Ice::Object::ice_twoway() const bool IceProxy::Ice::Object::ice_isTwoway() const { - return _reference->mode == Reference::ModeTwoway; + return _reference->getMode() == Reference::ModeTwoway; } ObjectPrx @@ -383,7 +383,7 @@ IceProxy::Ice::Object::ice_oneway() const bool IceProxy::Ice::Object::ice_isOneway() const { - return _reference->mode == Reference::ModeOneway; + return _reference->getMode() == Reference::ModeOneway; } ObjectPrx @@ -405,7 +405,7 @@ IceProxy::Ice::Object::ice_batchOneway() const bool IceProxy::Ice::Object::ice_isBatchOneway() const { - return _reference->mode == Reference::ModeBatchOneway; + return _reference->getMode() == Reference::ModeBatchOneway; } ObjectPrx @@ -427,7 +427,7 @@ IceProxy::Ice::Object::ice_datagram() const bool IceProxy::Ice::Object::ice_isDatagram() const { - return _reference->mode == Reference::ModeDatagram; + return _reference->getMode() == Reference::ModeDatagram; } ObjectPrx @@ -449,7 +449,7 @@ IceProxy::Ice::Object::ice_batchDatagram() const bool IceProxy::Ice::Object::ice_isBatchDatagram() const { - return _reference->mode == Reference::ModeBatchDatagram; + return _reference->getMode() == Reference::ModeBatchDatagram; } ObjectPrx @@ -552,6 +552,8 @@ ObjectPrx IceProxy::Ice::Object::ice_default() const { ReferencePtr ref = _reference->changeDefault(); + ref = ref->changeDefault(); + if(ref == _reference) { return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); @@ -638,12 +640,13 @@ IceProxy::Ice::Object::__handleException(const LocalException& ex, int& cnt) _delegate = 0; } - if(_reference->locatorInfo) + IndirectReferencePtr ir = IndirectReferencePtr::dynamicCast(_reference); + if(ir && ir->getLocatorInfo()) { - _reference->locatorInfo->clearObjectCache(_reference); + ir->getLocatorInfo()->clearObjectCache(ir); } - ProxyFactoryPtr proxyFactory = _reference->instance->proxyFactory(); + ProxyFactoryPtr proxyFactory = _reference->getInstance()->proxyFactory(); if(proxyFactory) { proxyFactory->checkRetryAfterException(ex, cnt); @@ -665,9 +668,10 @@ IceProxy::Ice::Object::__rethrowException(const LocalException& ex) _delegate = 0; } - if(_reference->locatorInfo) + IndirectReferencePtr ir = IndirectReferencePtr::dynamicCast(_reference); + if(ir && ir->getLocatorInfo()) { - _reference->locatorInfo->clearObjectCache(_reference); + ir->getLocatorInfo()->clearObjectCache(ir); } ex.ice_throw(); @@ -696,9 +700,9 @@ IceProxy::Ice::Object::__getDelegate() if(!_delegate) { - if(_reference->collocationOptimization) + if(_reference->getCollocationOptimization()) { - ObjectAdapterPtr adapter = _reference->instance->objectAdapterFactory()->findObjectAdapter(this); + ObjectAdapterPtr adapter = _reference->getInstance()->objectAdapterFactory()->findObjectAdapter(this); if(adapter) { Handle< ::IceDelegateD::Ice::Object> delegate = __createDelegateD(); @@ -718,9 +722,10 @@ IceProxy::Ice::Object::__getDelegate() // using a router, then add this proxy to the router info // object. // - if(_reference->routerInfo) + RoutableReferencePtr rr = RoutableReferencePtr::dynamicCast(_reference); + if(rr && rr->getRouterInfo()) { - _reference->routerInfo->addProxy(this); + rr->getRouterInfo()->addProxy(this); } } } @@ -743,7 +748,7 @@ IceProxy::Ice::Object::__createDelegateD() const Context& IceProxy::Ice::Object::__defaultContext() const { - return _reference->context; + return _reference->getContext(); } void @@ -862,7 +867,7 @@ IceDelegateM::Ice::Object::ice_invoke(const string& operation, BasicStream* __os = __out.os(); __os->writeBlob(inParams); bool ok = __out.invoke(); - if(__reference->mode == Reference::ModeTwoway) + if(__reference->getMode() == Reference::ModeTwoway) { try { @@ -1013,8 +1018,8 @@ IceDelegateD::Ice::Object::__initCurrent(Current& current, const string& op, Ope const Context& context) { current.adapter = __adapter; - current.id = __reference->identity; - current.facet = __reference->facet; + current.id = __reference->getIdentity(); + current.facet = __reference->getFacet(); current.operation = op; current.mode = mode; current.ctx = context; diff --git a/cpp/src/Ice/ProxyFactory.cpp b/cpp/src/Ice/ProxyFactory.cpp index 9f03eb70893..88ae9161766 100644 --- a/cpp/src/Ice/ProxyFactory.cpp +++ b/cpp/src/Ice/ProxyFactory.cpp @@ -61,7 +61,7 @@ IceInternal::ProxyFactory::proxyToStream(const ObjectPrx& proxy, BasicStream* s) { if(proxy) { - proxy->__reference()->identity.__write(s); + proxy->__reference()->getIdentity().__write(s); proxy->__reference()->streamWrite(s); } else diff --git a/cpp/src/Ice/Reference.cpp b/cpp/src/Ice/Reference.cpp index 8faf9e32e17..27045b5a9c0 100644 --- a/cpp/src/Ice/Reference.cpp +++ b/cpp/src/Ice/Reference.cpp @@ -32,186 +32,156 @@ using namespace IceInternal; void IceInternal::incRef(IceInternal::Reference* p) { p->__incRef(); } void IceInternal::decRef(IceInternal::Reference* p) { p->__decRef(); } -bool -IceInternal::Reference::operator==(const Reference& r) const +ReferencePtr +IceInternal::Reference::changeMode(Mode newMode) const { - if(this == &r) - { - return true; - } - - if(identity != r.identity) - { - return false; - } - - if(context != r.context) - { - return false; - } - - if(facet != r.facet) + if(newMode == mode) { - return false; + return ReferencePtr(const_cast<Reference*>(this)); } + ReferencePtr r = instance->referenceFactory()->clone(this); + r->mode = newMode; + return r; +} - if(mode != r.mode) +ReferencePtr +IceInternal::Reference::changeIdentity(const Identity& newIdentity) const +{ + if(newIdentity == identity) { - return false; + return ReferencePtr(const_cast<Reference*>(this)); } + ReferencePtr r = instance->referenceFactory()->clone(this); + r->identity = newIdentity; + return r; +} - if(secure != r.secure) +ReferencePtr +IceInternal::Reference::changeContext(const Context& newContext) const +{ + if(newContext == context) { - return false; + return ReferencePtr(const_cast<Reference*>(this)); } + ReferencePtr r = instance->referenceFactory()->clone(this); + r->context = newContext; + return r; +} - if(adapterId != r.adapterId) +ReferencePtr +IceInternal::Reference::changeFacet(const string& newFacet) const +{ + if(newFacet == facet) { - return false; + return ReferencePtr(const_cast<Reference*>(this)); } + ReferencePtr r = instance->referenceFactory()->clone(this); + r->facet = newFacet; + return r; +} - if(endpoints != r.endpoints) +ReferencePtr +IceInternal::Reference::changeSecure(bool newSecure) const +{ + if(newSecure == secure) { - return false; + return ReferencePtr(const_cast<Reference*>(this)); } + ReferencePtr r = instance->referenceFactory()->clone(this); + r->secure = newSecure; + return r; +} - if(routerInfo != r.routerInfo) +ReferencePtr +IceInternal::Reference::changeCollocationOptimization(bool newCollocationOptimization) const +{ + if(newCollocationOptimization == collocationOptimization) { - return false; + return ReferencePtr(const_cast<Reference*>(this)); } + ReferencePtr r = instance->referenceFactory()->clone(this); + r->collocationOptimization = newCollocationOptimization; + return r; +} - if(locatorInfo != r.locatorInfo) - { - return false; - } +ReferencePtr +IceInternal::Reference::changeRouter(const RouterPrx&) const +{ + return ReferencePtr(const_cast<Reference*>(this)); +} - if(fixedConnections != r.fixedConnections) - { - return false; - } +ReferencePtr +IceInternal::Reference::changeLocator(const LocatorPrx&) const +{ + return ReferencePtr(const_cast<Reference*>(this)); +} - if(collocationOptimization != r.collocationOptimization) - { - return false; - } +ReferencePtr +IceInternal::Reference::changeDefault() const +{ + return ReferencePtr(const_cast<Reference*>(this)); +} - return true; +ReferencePtr +IceInternal::Reference::changeCompress(bool) const +{ + return ReferencePtr(const_cast<Reference*>(this)); } -bool -IceInternal::Reference::operator!=(const Reference& r) const +ReferencePtr +IceInternal::Reference::changeTimeout(int) const { - return !operator==(r); + return ReferencePtr(const_cast<Reference*>(this)); } -bool -IceInternal::Reference::operator<(const Reference& r) const +Int +Reference::hash() const { - if(this == &r) - { - return false; - } - - if(identity < r.identity) - { - return true; - } - else if(r.identity < identity) - { - return false; - } - - if(context < r.context) - { - return true; - } - else if(r.context < context) - { - return false; - } + IceUtil::Mutex::Lock sync(hashMutex); - if(facet < r.facet) - { - return true; - } - else if(r.facet < facet) + if(hashInitialized) { - return false; + return hashValue; } - 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(adapterId < r.adapterId) - { - return true; - } - else if(r.adapterId < adapterId) - { - return false; - } - - if(endpoints < r.endpoints) - { - return true; - } - else if(r.endpoints < endpoints) - { - return false; - } - - if(routerInfo < r.routerInfo) - { - return true; - } - else if(r.routerInfo < routerInfo) - { - return false; - } - - if(locatorInfo < r.locatorInfo) - { - return true; - } - else if(r.locatorInfo < locatorInfo) - { - return false; - } - - if(fixedConnections < r.fixedConnections) + string::const_iterator p; + Context::const_iterator q; + + Int h = static_cast<Int>(mode); + + for(p = identity.name.begin(); p != identity.name.end(); ++p) { - return true; + h = 5 * h + *p; } - else if(r.fixedConnections < fixedConnections) + + for(p = identity.category.begin(); p != identity.category.end(); ++p) { - return false; + h = 5 * h + *p; } - - if(!collocationOptimization && r.collocationOptimization) + + for(q = context.begin(); q != context.end(); ++q) { - return true; + 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; + } } - else if(r.collocationOptimization < collocationOptimization) + + for(p = facet.begin(); p != facet.end(); ++p) { - return false; + h = 5 * h + *p; } - return false; + h = 5 * h + static_cast<Int>(secure); + + hashValue = h; + hashInitialized = true; + + return h; } void @@ -240,23 +210,7 @@ IceInternal::Reference::streamWrite(BasicStream* s) const s->write(secure); - s->writeSize(Ice::Int(endpoints.size())); - - if(!endpoints.empty()) - { - assert(adapterId.empty()); - - vector<EndpointPtr>::const_iterator p; - - for(p = endpoints.begin(); p != endpoints.end(); ++p) - { - (*p)->streamWrite(s); - } - } - else - { - s->write(adapterId); - } + // Derived class writes the remainder of the reference. } string @@ -337,353 +291,850 @@ IceInternal::Reference::toString() const s << " -s"; } - if(!endpoints.empty()) + return s.str(); + + // 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(identity != r.identity) + { + return false; + } + + if(context != r.context) + { + return false; + } + + if(facet != r.facet) + { + return false; + } + + if(secure != r.secure) + { + return false; + } + + if(collocationOptimization != r.collocationOptimization) + { + 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(identity < r.identity) + { + return true; + } + else if(r.identity < identity) + { + 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; + } + + if(!secure && r.secure) + { + return true; + } + else if(r.secure < secure) + { + return false; + } + + if(!collocationOptimization && r.collocationOptimization) + { + return true; + } + else if(r.collocationOptimization < collocationOptimization) + { + return false; + } + + return false; +} + +class ConnectionIsDatagram : public unary_function<ConnectionIPtr, bool> +{ +public: + + bool + operator()(ConnectionIPtr p) const + { + return p->endpoint()->datagram(); + } +}; + +class ConnectionIsSecure : public unary_function<ConnectionIPtr, bool> +{ +public: + + bool + operator()(ConnectionIPtr p) const { - assert(adapterId.empty()); + return p->endpoint()->secure(); + } +}; + +vector<ConnectionIPtr> +IceInternal::Reference::filterConnections(const vector<ConnectionIPtr>& allConnections) const +{ + vector<ConnectionIPtr> connections = allConnections; - vector<EndpointPtr>::const_iterator p; - for(p = endpoints.begin(); p != endpoints.end(); ++p) + switch(mode) + { + case ModeTwoway: + case ModeOneway: + case ModeBatchOneway: { - string endp = (*p)->toString(); - if(!endp.empty()) - { - s << ':' << endp; - } + // + // Filter out datagram connections. + // + connections.erase(remove_if(connections.begin(), connections.end(), ConnectionIsDatagram()), + connections.end()); + break; + } + + case ModeDatagram: + case ModeBatchDatagram: + { + // + // Filter out non-datagram connections. + // + connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsDatagram())), + connections.end()); + break; } } - else if(!adapterId.empty()) + + // + // Randomize the order of connections. + // + random_shuffle(connections.begin(), connections.end()); + + // + // If a secure connection is requested, remove all non-secure + // connections. Otherwise make non-secure connections preferred over + // secure connections by partitioning the connection vector, so that + // non-secure connections come first. + // + if(secure) + { + connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsSecure())), + connections.end()); + } + else { - string a = IceUtil::escapeString(adapterId, ""); - // - // If the encoded adapter id string contains characters which - // the reference parser uses as separators, then we enclose - // the adapter id string in quotes. - // - s << " @ "; - if(a.find_first_of(" \t\n\r") != string::npos) - { - s << '"' << a << '"'; - } - else - { - s << adapterId; - } + // + // We must use stable_partition() instead of just simply + // partition(), because otherwise some STL implementations + // order our now randomized connections. + // + stable_partition(connections.begin(), connections.end(), not1(ConnectionIsSecure())); } - return s.str(); + return connections; } -ReferencePtr -IceInternal::Reference::changeIdentity(const Identity& newIdentity) const +IceInternal::Reference::Reference(const InstancePtr& inst, const Ice::Identity& ident, const Ice::Context& ctx, + const std::string& fs, Mode md, bool sec, bool collocationOpt) + : instance(inst), + mode(md), + identity(ident), + context(ctx), + facet(fs), + secure(sec), + collocationOptimization(collocationOpt), + hashInitialized(false) { - if(newIdentity == identity) +} + +IceInternal::Reference::Reference(const Reference& r) +{ + instance = r.instance; + mode = r.mode; + identity = r.identity; + context = r.context; + facet = r.facet; + secure = r.secure; + collocationOptimization = r.collocationOptimization; + 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 Ice::Identity& ident, + const Ice::Context& ctx, const std::string& fs, Mode md, + bool sec, bool collocationOpt, + const vector<Ice::ConnectionIPtr>& fixedConns) + : Reference(inst, ident, ctx, fs, md, sec, collocationOpt), + fixedConnections(fixedConns) +{ +} + +vector<EndpointPtr> +IceInternal::FixedReference::getEndpoints() const +{ + return vector<EndpointPtr>(); +} + +void +IceInternal::FixedReference::streamWrite(BasicStream* s) const +{ + MarshalException ex(__FILE__, __LINE__); + ex.reason = "Cannot marshal a fixed reference"; + throw ex; +} + +string +IceInternal::FixedReference::toString() const +{ + MarshalException ex(__FILE__, __LINE__); + ex.reason = "Cannot stringify a fixed reference"; + throw ex; +} + +ConnectionIPtr +IceInternal::FixedReference::getConnection(bool& compress) const +{ + vector<ConnectionIPtr> filteredConns = filterConnections(fixedConnections); + if(filteredConns.empty()) { - return ReferencePtr(const_cast<Reference*>(this)); + NoEndpointException ex(__FILE__, __LINE__); + ex.proxy = toString(); + throw ex; } - else + + ConnectionIPtr connection = filteredConns[0]; + assert(connection); + compress = connection->endpoint()->compress(); + + return connection; +} + +bool +IceInternal::FixedReference::operator==(const Reference& r) const +{ + if(this == &r) + { + return true; + } + const FixedReference* rhs = dynamic_cast<const FixedReference*>(&r); + if(!rhs || !Reference::operator==(r)) { - return instance->referenceFactory()->create(newIdentity, context, facet, mode, secure, adapterId, - endpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + return false; } + return fixedConnections == rhs->fixedConnections; } -ReferencePtr -IceInternal::Reference::changeContext(const Context& newContext) const +bool +IceInternal::FixedReference::operator!=(const Reference& r) const { - if(newContext == context) + return !operator==(r); +} + +bool +IceInternal::FixedReference::operator<(const Reference& r) const +{ + if(this == &r) { - return ReferencePtr(const_cast<Reference*>(this)); + return false; } - else + const FixedReference* rhs = dynamic_cast<const FixedReference*>(&r); + if(!rhs || !Reference::operator<(r)) { - return instance->referenceFactory()->create(identity, newContext, facet, mode, secure, adapterId, - endpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + return false; } + return fixedConnections < rhs->fixedConnections; } ReferencePtr -IceInternal::Reference::changeFacet(const string& newFacet) const +IceInternal::FixedReference::clone() const { - if(newFacet == facet) + return new FixedReference(*this); +} + +IceInternal::FixedReference::FixedReference(const FixedReference& r) + : Reference(r) +{ + fixedConnections = r.fixedConnections; +} + +void IceInternal::incRef(IceInternal::RoutableReference* p) { p->__incRef(); } +void IceInternal::decRef(IceInternal::RoutableReference* p) { p->__decRef(); } + +std::vector<EndpointPtr> +IceInternal::RoutableReference::getRoutedEndpoints() const +{ + if(routerInfo) { - return ReferencePtr(const_cast<Reference*>(this)); + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + ObjectPrx clientProxy = routerInfo->getClientProxy(); + return clientProxy->__reference()->getEndpoints(); } - else + return vector<EndpointPtr>(); +} + +ReferencePtr +IceInternal::RoutableReference::changeRouter(const RouterPrx& newRouter) const +{ + RouterInfoPtr newRouterInfo = getInstance()->routerManager()->get(newRouter); + if(newRouterInfo == routerInfo) { - return instance->referenceFactory()->create(identity, context, newFacet, mode, secure, adapterId, - endpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + return RoutableReferencePtr(const_cast<RoutableReference*>(this)); } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this)); + r->routerInfo = newRouterInfo; + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeDefault() const +{ + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this)); + r->routerInfo = getInstance()->routerManager()->get(getInstance()->referenceFactory()->getDefaultRouter()); + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeCompress(bool newCompress) const +{ + return RoutableReferencePtr(const_cast<RoutableReference*>(this)); } ReferencePtr -IceInternal::Reference::changeTimeout(int newTimeout) const +IceInternal::RoutableReference::changeTimeout(int newTimeout) const +{ + return RoutableReferencePtr(const_cast<RoutableReference*>(this)); +} + +void +IceInternal::RoutableReference::streamWrite(BasicStream* s) const +{ + Reference::streamWrite(s); +} + +string +IceInternal::RoutableReference::toString() const +{ + return Reference::toString(); +} + +bool +IceInternal::RoutableReference::operator==(const Reference& r) const { // - // We change the timeout settings in all endpoints. + // Note: if(this == &r) test is performed by each non-abstract derived class. // - vector<EndpointPtr>::const_iterator p; - vector<EndpointPtr> newEndpoints; - for(p = endpoints.begin(); p != endpoints.end(); ++p) + const RoutableReference* rhs = dynamic_cast<const RoutableReference*>(&r); + if(!rhs || !Reference::operator==(r)) { - newEndpoints.push_back((*p)->timeout(newTimeout)); + return false; } - - return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId, - newEndpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + return routerInfo == rhs->routerInfo; } -ReferencePtr -IceInternal::Reference::changeMode(Mode newMode) const +bool +IceInternal::RoutableReference::operator!=(const Reference& r) const { - if(newMode == mode) + return !operator==(r); +} + +bool +IceInternal::RoutableReference::operator<(const Reference& r) const +{ + if(this == &r) { - return ReferencePtr(const_cast<Reference*>(this)); + return false; } - else + const RoutableReference* rhs = dynamic_cast<const RoutableReference*>(&r); + if(!rhs || !Reference::operator<(r)) { - return instance->referenceFactory()->create(identity, context, facet, newMode, secure, adapterId, - endpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + return false; } + return routerInfo < rhs->routerInfo; } -ReferencePtr -IceInternal::Reference::changeSecure(bool newSecure) const +IceInternal::RoutableReference::RoutableReference(const InstancePtr& inst, const Ice::Identity& ident, + const Ice::Context& ctx, const std::string& fs, Mode md, + bool sec, const RouterInfoPtr& rtrInfo, bool collocationOpt) + : Reference(inst, ident, ctx, fs, md, sec, collocationOpt), + routerInfo(rtrInfo) { - if(newSecure == secure) +} + +IceInternal::RoutableReference::RoutableReference(const RoutableReference& r) + : Reference(r) +{ + routerInfo = r.routerInfo; +} + +void IceInternal::incRef(IceInternal::DirectReference* p) { p->__incRef(); } +void IceInternal::decRef(IceInternal::DirectReference* p) { p->__decRef(); } + +IceInternal::DirectReference::DirectReference(const InstancePtr& inst, const Ice::Identity& ident, + const Ice::Context& ctx, const std::string& fs, Mode md, + bool sec, const std::vector<EndpointPtr>& endpts, + const RouterInfoPtr& rtrInfo, bool collocationOpt) + : RoutableReference(inst, ident, ctx, fs, md, sec, rtrInfo, collocationOpt), + endpoints(endpts) +{ +} + +vector<EndpointPtr> +IceInternal::DirectReference::getEndpoints() const +{ + return endpoints; +} + +DirectReferencePtr +IceInternal::DirectReference::changeEndpoints(const vector<EndpointPtr>& newEndpoints) const +{ + if(newEndpoints == endpoints) { - return ReferencePtr(const_cast<Reference*>(this)); + return DirectReferencePtr(const_cast<DirectReference*>(this)); } - else + DirectReferencePtr r = DirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this)); + r->endpoints = newEndpoints; + return r; +} + +ReferencePtr +IceInternal::DirectReference::changeCompress(bool newCompress) const +{ + DirectReferencePtr r = DirectReferencePtr::dynamicCast(RoutableReference::changeCompress(newCompress)); + vector<EndpointPtr> newEndpoints; + vector<EndpointPtr>::const_iterator p; + for(p = endpoints.begin(); p != endpoints.end(); ++p) { - return instance->referenceFactory()->create(identity, context, facet, mode, newSecure, adapterId, - endpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + newEndpoints.push_back((*p)->compress(newCompress)); } + r->endpoints = newEndpoints; + return r; } ReferencePtr -IceInternal::Reference::changeCompress(bool newCompress) const +IceInternal::DirectReference::changeTimeout(int newTimeout) const { - // - // We change the compress settings in all endpoints. - // + DirectReferencePtr r = DirectReferencePtr::dynamicCast(RoutableReference::changeTimeout(newTimeout)); + vector<EndpointPtr> newEndpoints; vector<EndpointPtr>::const_iterator p; + for(p = endpoints.begin(); p != endpoints.end(); ++p) + { + newEndpoints.push_back((*p)->timeout(newTimeout)); + } + r->endpoints = newEndpoints; + return r; +} - vector<EndpointPtr> newEndpoints; +void +IceInternal::DirectReference::streamWrite(BasicStream* s) const +{ + RoutableReference::streamWrite(s); + + s->writeSize(Ice::Int(endpoints.size())); + vector<EndpointPtr>::const_iterator p; for(p = endpoints.begin(); p != endpoints.end(); ++p) { - newEndpoints.push_back((*p)->compress(newCompress)); + (*p)->streamWrite(s); } - - return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId, - newEndpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); } -ReferencePtr -IceInternal::Reference::changeAdapterId(const string& newAdapterId) const +string +IceInternal::DirectReference::toString() const { - if(newAdapterId == adapterId) + string result = RoutableReference::toString(); + + vector<EndpointPtr>::const_iterator p; + for(p = endpoints.begin(); p != endpoints.end(); ++p) { - return ReferencePtr(const_cast<Reference*>(this)); + string endp = (*p)->toString(); + if(!endp.empty()) + { + result.append(":"); + result.append(endp); + } } - else + return result; +} + +ConnectionIPtr +IceInternal::DirectReference::getConnection(bool& comp) const +{ + vector<EndpointPtr> endpts = RoutableReference::getRoutedEndpoints(); + if(endpts.empty()) + { + endpts = endpoints; + } + vector<EndpointPtr> filteredEndpoints = filterEndpoints(endpts, getMode(), getSecure()); + if(filteredEndpoints.empty()) { - return instance->referenceFactory()->create(identity, context, facet, mode, secure, newAdapterId, - endpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + NoEndpointException ex(__FILE__, __LINE__); + ex.proxy = toString(); + throw ex; } + + OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); + ConnectionIPtr connection = factory->create(filteredEndpoints, comp); + assert(connection); + + // + // 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()); + } + + assert(connection); + return connection; } -ReferencePtr -IceInternal::Reference::changeEndpoints(const vector<EndpointPtr>& newEndpoints) const +bool +IceInternal::DirectReference::operator==(const Reference& r) const { - if(newEndpoints == endpoints) + if(this == &r) { - return ReferencePtr(const_cast<Reference*>(this)); + return true; } - else + const DirectReference* rhs = dynamic_cast<const DirectReference*>(&r); + if(!rhs || !RoutableReference::operator==(r)) { - return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId, - newEndpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + return false; } + return endpoints == rhs->endpoints; } -ReferencePtr -IceInternal::Reference::changeRouter(const RouterPrx& newRouter) const +bool +IceInternal::DirectReference::operator!=(const Reference& r) const { - RouterInfoPtr newRouterInfo = instance->routerManager()->get(newRouter); + return !operator==(r); +} - if(newRouterInfo == routerInfo) +bool +IceInternal::DirectReference::operator<(const Reference& r) const +{ + if(this == &r) { - return ReferencePtr(const_cast<Reference*>(this)); + return false; } - else + const DirectReference* rhs = dynamic_cast<const DirectReference*>(&r); + if(!rhs || !RoutableReference::operator<(r)) { - return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId, - endpoints, newRouterInfo, locatorInfo, fixedConnections, - collocationOptimization); + return false; } + return endpoints < rhs->endpoints; } ReferencePtr -IceInternal::Reference::changeLocator(const LocatorPrx& newLocator) const +IceInternal::DirectReference::clone() const { - LocatorInfoPtr newLocatorInfo = instance->locatorManager()->get(newLocator); + return new DirectReference(*this); +} - if(newLocatorInfo == locatorInfo) +IceInternal::DirectReference::DirectReference(const DirectReference& r) + : RoutableReference(r) +{ + endpoints = r.endpoints; +} + + +void IceInternal::incRef(IceInternal::IndirectReference* p) { p->__incRef(); } +void IceInternal::decRef(IceInternal::IndirectReference* p) { p->__decRef(); } + +IceInternal::IndirectReference::IndirectReference(const InstancePtr& inst, const Ice::Identity& ident, + const Ice::Context& ctx, const std::string& fs, Mode md, + bool sec, const string& adptid, const RouterInfoPtr& rtrInfo, + const LocatorInfoPtr& locInfo, bool collocationOpt) + : RoutableReference(inst, ident, ctx, fs, md, sec, rtrInfo, collocationOpt), + adapterId(adptid), + locatorInfo(locInfo) +{ +} + +vector<EndpointPtr> +IceInternal::IndirectReference::getEndpoints() const +{ + return vector<EndpointPtr>(); +} + +IndirectReferencePtr +IceInternal::IndirectReference::changeAdapterId(const string& newAdapterId) const +{ + if(newAdapterId == adapterId) { - return ReferencePtr(const_cast<Reference*>(this)); + return IndirectReferencePtr(const_cast<IndirectReference*>(this)); } - else + IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this)); + r->adapterId = adapterId; + return r; +} + +ReferencePtr +IceInternal::IndirectReference::changeLocator(const LocatorPrx& newLocator) const +{ + LocatorInfoPtr newLocatorInfo = getInstance()->locatorManager()->get(newLocator); + + if(newLocatorInfo == locatorInfo) { - return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId, - endpoints, routerInfo, newLocatorInfo, fixedConnections, - collocationOptimization); + return IndirectReferencePtr(const_cast<IndirectReference*>(this)); } + IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this)); + r->locatorInfo = newLocatorInfo; + return r; } ReferencePtr -IceInternal::Reference::changeCollocationOptimization(bool newCollocationOptimization) const +IceInternal::IndirectReference::changeDefault() const { - if(newCollocationOptimization == collocationOptimization) + IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(RoutableReference::changeDefault()); + r->locatorInfo = getInstance()->locatorManager()->get(getInstance()->referenceFactory()->getDefaultLocator()); + return r; +} + +ReferencePtr +IceInternal::IndirectReference::changeCompress(bool newCompress) const +{ + IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(RoutableReference::changeCompress(newCompress)); + if(locatorInfo) { - return ReferencePtr(const_cast<Reference*>(this)); + LocatorPrx newLocator = LocatorPrx::uncheckedCast(locatorInfo->getLocator()->ice_compress(newCompress)); + r->locatorInfo = getInstance()->locatorManager()->get(newLocator); } - else + return r; +} + +ReferencePtr +IceInternal::IndirectReference::changeTimeout(int newTimeout) const +{ + IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(RoutableReference::changeTimeout(newTimeout)); + LocatorInfoPtr newLocatorInfo; + if(locatorInfo) { - return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId, - endpoints, routerInfo, locatorInfo, fixedConnections, - newCollocationOptimization); + LocatorPrx newLocator = LocatorPrx::uncheckedCast(locatorInfo->getLocator()->ice_timeout(newTimeout)); + r->locatorInfo = getInstance()->locatorManager()->get(newLocator); } + return r; } -ReferencePtr -IceInternal::Reference::changeDefault() const +void +IceInternal::IndirectReference::streamWrite(BasicStream* s) const { - RouterInfoPtr defaultRouterInfo = instance->routerManager()-> - get(instance->referenceFactory()->getDefaultRouter()); - LocatorInfoPtr defaultLocatorInfo = instance->locatorManager()-> - get(instance->referenceFactory()->getDefaultLocator()); + RoutableReference::streamWrite(s); - return instance->referenceFactory()->create(identity, context, "", ModeTwoway, false, adapterId, - endpoints, defaultRouterInfo, defaultLocatorInfo, - vector<ConnectionIPtr>(), true); + s->writeSize(0); + s->write(adapterId); } -ConnectionIPtr -IceInternal::Reference::getConnection(bool& compress) const +string +IceInternal::IndirectReference::toString() const { - ConnectionIPtr connection; + string result = RoutableReference::toString(); + if(adapterId.empty()) + { + return result; + } + result.append(" @ "); // - // If we have a fixed connection, we return such fixed connection. + // If the encoded adapter id string contains characters which + // the reference parser uses as separators, then we enclose + // the adapter id string in quotes. // - if(!fixedConnections.empty()) + 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; +} + +ConnectionIPtr +IceInternal::IndirectReference::getConnection(bool& comp) const +{ + ConnectionIPtr connection; + + while(true) { - vector<ConnectionIPtr> filteredConns = filterConnections(fixedConnections); - if(filteredConns.empty()) + vector<EndpointPtr> endpts = RoutableReference::getRoutedEndpoints(); + bool cached; + if(endpts.empty() && locatorInfo) + { + const IndirectReferencePtr self = const_cast<IndirectReference*>(this); + endpts = locatorInfo->getEndpoints(self, cached); + } + vector<EndpointPtr> filteredEndpoints = filterEndpoints(endpts, getMode(), getSecure()); + if(filteredEndpoints.empty()) { NoEndpointException ex(__FILE__, __LINE__); ex.proxy = toString(); throw ex; } - connection = filteredConns[0]; - compress = connection->endpoint()->compress(); - } - else - { - while(true) + try { - bool cached; - vector<EndpointPtr> endpts; - - if(routerInfo) - { - // - // If we route, we send everything to the router's client - // proxy endpoints. - // - ObjectPrx clientProxy = routerInfo->getClientProxy(); - endpts = clientProxy->__reference()->endpoints; - } - else if(!endpoints.empty()) - { - endpts = endpoints; - } - else if(locatorInfo) - { - ReferencePtr self = const_cast<Reference*>(this); - endpts = locatorInfo->getEndpoints(self, cached); - } - - vector<EndpointPtr> filteredEndpts = filterEndpoints(endpts); - if(filteredEndpts.empty()) - { - NoEndpointException ex(__FILE__, __LINE__); - ex.proxy = toString(); - throw ex; - } - - try - { - OutgoingConnectionFactoryPtr factory = instance->outgoingConnectionFactory(); - connection = factory->create(filteredEndpts, compress); - assert(connection); - } - catch(const LocalException& ex) + OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); + connection = factory->create(filteredEndpoints, comp); + assert(connection); + } + catch(const LocalException& ex) + { + if(!getRouterInfo()) { - if(!routerInfo && endpoints.empty()) - { - assert(locatorInfo); - ReferencePtr self = const_cast<Reference*>(this); - locatorInfo->clearCache(self); - - if(cached) + assert(locatorInfo); + const IndirectReferencePtr self = const_cast<IndirectReference*>(this); + locatorInfo->clearCache(self); + + if(cached) + { + TraceLevelsPtr traceLevels = getInstance()->traceLevels(); + LoggerPtr logger = getInstance()->logger(); + if(traceLevels->retry >=2) { - TraceLevelsPtr traceLevels = instance->traceLevels(); - LoggerPtr logger = instance->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; - } - continue; + Trace out(logger, traceLevels->retryCat); + out << "connection to cached endpoints failed\n" + << "removing endpoints from cache and trying one more time\n" << ex; } + continue; } - - throw; } - - break; - } - - // - // 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(routerInfo) - { - connection->setAdapter(routerInfo->getAdapter()); + + throw; } + + break; + } + + // + // 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()); } assert(connection); return connection; } +bool +IceInternal::IndirectReference::operator==(const Reference& r) const +{ + if(this == &r) + { + return true; + } + const IndirectReference* rhs = dynamic_cast<const IndirectReference*>(&r); + if(!rhs || !RoutableReference::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; + } + const IndirectReference* rhs = dynamic_cast<const IndirectReference*>(&r); + if(!rhs || !RoutableReference::operator<(r)) + { + return false; + } + return adapterId < rhs->adapterId && locatorInfo < rhs->locatorInfo; +} + +ReferencePtr +IceInternal::IndirectReference::clone() const +{ + return new IndirectReference(*this); +} + +IceInternal::IndirectReference::IndirectReference(const IndirectReference& r) + : RoutableReference(r) +{ + adapterId = r.adapterId; + locatorInfo = r.locatorInfo; +} + vector<EndpointPtr> -IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints) const +IceInternal::filterEndpoints(const vector<EndpointPtr>& allEndpoints, Reference::Mode m, bool sec) { vector<EndpointPtr> endpoints = allEndpoints; @@ -693,11 +1144,11 @@ IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints) endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), Ice::constMemFun(&Endpoint::unknown)), endpoints.end()); - switch(mode) + switch(m) { - case ModeTwoway: - case ModeOneway: - case ModeBatchOneway: + case Reference::ModeTwoway: + case Reference::ModeOneway: + case Reference::ModeBatchOneway: { // // Filter out datagram endpoints. @@ -707,8 +1158,8 @@ IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints) break; } - case ModeDatagram: - case ModeBatchDatagram: + case Reference::ModeDatagram: + case Reference::ModeBatchDatagram: { // // Filter out non-datagram endpoints. @@ -731,7 +1182,7 @@ IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints) // secure endpoints by partitioning the endpoint vector, so that // non-secure endpoints come first. // - if(secure) + if(sec) { endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), not1(Ice::constMemFun(&Endpoint::secure))), endpoints.end()); @@ -749,160 +1200,3 @@ IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints) return endpoints; } -class ConnectionIsDatagram : public unary_function<ConnectionIPtr, bool> -{ -public: - - bool - operator()(ConnectionIPtr p) const - { - return p->endpoint()->datagram(); - } -}; - -class ConnectionIsSecure : public unary_function<ConnectionIPtr, bool> -{ -public: - - bool - operator()(ConnectionIPtr p) const - { - return p->endpoint()->secure(); - } -}; - -vector<ConnectionIPtr> -IceInternal::Reference::filterConnections(const vector<ConnectionIPtr>& allConnections) const -{ - vector<ConnectionIPtr> connections = allConnections; - - switch(mode) - { - case ModeTwoway: - case ModeOneway: - case ModeBatchOneway: - { - // - // Filter out datagram connections. - // - connections.erase(remove_if(connections.begin(), connections.end(), ConnectionIsDatagram()), - connections.end()); - break; - } - - case ModeDatagram: - case ModeBatchDatagram: - { - // - // Filter out non-datagram connections. - // - connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsDatagram())), - connections.end()); - break; - } - } - - // - // Randomize the order of connections. - // - random_shuffle(connections.begin(), connections.end()); - - // - // If a secure connection is requested, remove all non-secure - // connections. Otherwise make non-secure connections preferred over - // secure connections by partitioning the connection vector, so that - // non-secure connections come first. - // - if(secure) - { - connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsSecure())), - connections.end()); - } - else - { - // - // We must use stable_partition() instead of just simply - // partition(), because otherwise some STL implementations - // order our now randomized connections. - // - stable_partition(connections.begin(), connections.end(), not1(ConnectionIsSecure())); - } - - return connections; -} - -IceInternal::Reference::Reference(const InstancePtr& inst, - const Identity& ident, - const Context& ctx, - const string& fs, - Mode md, - bool sec, - const string& adptid, - const vector<EndpointPtr>& endpts, - const RouterInfoPtr& rtrInfo, - const LocatorInfoPtr& locInfo, - const vector<ConnectionIPtr>& fixedConns, - bool collocationOpt) : - instance(inst), - identity(ident), - context(ctx), - facet(fs), - mode(md), - secure(sec), - adapterId(adptid), - endpoints(endpts), - routerInfo(rtrInfo), - locatorInfo(locInfo), - fixedConnections(fixedConns), - collocationOptimization(collocationOpt), - hashValue(0) -{ - // - // It's either adapter id or endpoints, it can't be both. - // - assert(!(!adapterId.empty() && !endpoints.empty())); - - Int h = 0; - - string::const_iterator p; - Context::const_iterator q; - - 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; - } - - 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<Int>(mode); - - h = 5 * h + static_cast<Int>(secure); - - // - // TODO: Should we also take the endpoints and other stuff into - // account for hash calculation? Perhaps not, the code above - // should be good enough for a good hash value. - // - - const_cast<Int&>(hashValue) = h; -} diff --git a/cpp/src/Ice/Reference.h b/cpp/src/Ice/Reference.h index ae81062013c..91a99a8b5f8 100644 --- a/cpp/src/Ice/Reference.h +++ b/cpp/src/Ice/Reference.h @@ -11,6 +11,7 @@ #define ICE_REFERENCE_H #include <IceUtil/Shared.h> +#include <IceUtil/Mutex.h> #include <Ice/ReferenceF.h> #include <Ice/ReferenceFactoryF.h> #include <Ice/EndpointF.h> @@ -41,73 +42,245 @@ public: ModeLast = ModeBatchDatagram }; - bool operator==(const Reference&) const; - bool operator!=(const Reference&) const; - bool operator<(const Reference&) const; + Mode getMode() const { return mode; } + const ::Ice::Identity& getIdentity() const { return identity; } + const ::Ice::Context& getContext() const { return context; } + const ::std::string& getFacet() const { return facet; } + bool getSecure() const { return secure; } + bool getCollocationOptimization() const { return collocationOptimization; } + const InstancePtr& getInstance() const { return instance; } - // - // Marshal the reference. - // - void streamWrite(BasicStream*) const; + virtual ::std::vector<EndpointPtr> getEndpoints() const = 0; // - // Convert the reference to its string form. + // The change* methods (here and in derived classes) create + // a new reference based on the existing one, with the + // corresponding value changed. // - std::string toString() const; + ReferencePtr changeMode(Mode) const; + ReferencePtr changeIdentity(const ::Ice::Identity&) const; + ReferencePtr changeContext(const ::Ice::Context&) const; + ReferencePtr changeFacet(const ::std::string&) const; + ReferencePtr changeSecure(bool) const; + ReferencePtr changeCollocationOptimization(bool) const; + + virtual ReferencePtr changeRouter(const ::Ice::RouterPrx&) const; + virtual ReferencePtr changeLocator(const ::Ice::LocatorPrx&) const; + virtual ReferencePtr changeDefault() const; + virtual ReferencePtr changeCompress(bool) const; + virtual ReferencePtr changeTimeout(int) const; + + virtual int hash() const; // Conceptually const. // - // All members are const, because References are immutable. + // Marshal the reference. // - const InstancePtr instance; - const Ice::Identity identity; - const Ice::Context context; - const std::string facet; - const Mode mode; - const bool secure; - const std::string adapterId; - const std::vector<EndpointPtr> endpoints; - const RouterInfoPtr routerInfo; // Null if no router is used. - const LocatorInfoPtr locatorInfo; // Null if no locator is used. - const std::vector<Ice::ConnectionIPtr> fixedConnections; // For using fixed connections, otherwise empty. - const bool collocationOptimization; - const Ice::Int hashValue; + virtual void streamWrite(BasicStream*) const = 0; // - // Get a new reference, based on the existing one, overwriting - // certain values. + // Convert the reference to its string form. // - ReferencePtr changeIdentity(const Ice::Identity&) const; - ReferencePtr changeContext(const Ice::Context&) const; - ReferencePtr changeFacet(const std::string&) const; - ReferencePtr changeTimeout(int) const; - ReferencePtr changeMode(Mode) const; - ReferencePtr changeSecure(bool) const; - ReferencePtr changeCompress(bool) const; - ReferencePtr changeAdapterId(const std::string&) const; - ReferencePtr changeEndpoints(const std::vector<EndpointPtr>&) const; - ReferencePtr changeRouter(const ::Ice::RouterPrx&) const; - ReferencePtr changeLocator(const ::Ice::LocatorPrx&) const; - ReferencePtr changeCollocationOptimization(bool) const; - ReferencePtr changeDefault() const; - + virtual ::std::string toString() const = 0; + // // Get a suitable connection for this reference. // - Ice::ConnectionIPtr getConnection(bool&) const; + virtual ::Ice::ConnectionIPtr getConnection(bool&) const = 0; + + ::std::vector< ::Ice::ConnectionIPtr> filterConnections(const ::std::vector< ::Ice::ConnectionIPtr>&) const; + + virtual bool operator==(const Reference&) const = 0; + virtual bool operator!=(const Reference&) const = 0; + virtual bool operator<(const Reference&) const = 0; + + virtual ReferencePtr clone() const = 0; + +protected: + + Reference(const InstancePtr&, const ::Ice::Identity&, const ::Ice::Context&, const ::std::string&, + Mode, bool, bool); + Reference(const Reference&); + virtual ~Reference() {} + +private: + + InstancePtr instance; + + Mode mode; + ::Ice::Identity identity; + ::Ice::Context context; + ::std::string facet; + bool secure; + bool collocationOptimization; + + ::IceUtil::Mutex hashMutex; // For lazy initialization of hash value. + mutable ::Ice::Int hashValue; + mutable bool hashInitialized; +}; + +class FixedReference : public Reference +{ +public: + + FixedReference(const InstancePtr&, const ::Ice::Identity&, const ::Ice::Context&, const ::std::string&, Mode, bool, + bool, const ::std::vector< ::Ice::ConnectionIPtr>&); + + const ::std::vector< ::Ice::ConnectionIPtr>& getFixedConnections() const { return fixedConnections; } + + virtual ::std::vector<EndpointPtr> getEndpoints() const; + + virtual void streamWrite(BasicStream*) const; + virtual ::std::string toString() const; + virtual ::Ice::ConnectionIPtr getConnection(bool&) const; + + virtual bool operator==(const Reference&) const; + virtual bool operator!=(const Reference&) const; + virtual bool operator<(const Reference&) const; + + virtual ReferencePtr clone() const; + +protected: + + FixedReference(const FixedReference&); + virtual ~FixedReference() {} + +private: + + ::std::vector< ::Ice::ConnectionIPtr> fixedConnections; +}; + +class RoutableReference : public Reference +{ +public: + + const RouterInfoPtr& getRouterInfo() const { return routerInfo; } + ::std::vector<EndpointPtr> getRoutedEndpoints() const; + + virtual ReferencePtr changeRouter(const ::Ice::RouterPrx&) const; + virtual ReferencePtr changeDefault() const; + virtual ReferencePtr changeCompress(bool) const; + virtual ReferencePtr changeTimeout(int) const; + + virtual void streamWrite(BasicStream*) const = 0; + virtual ::std::string toString() const = 0; + virtual ::Ice::ConnectionIPtr getConnection(bool&) const = 0; + + virtual bool operator==(const Reference&) const = 0; + virtual bool operator!=(const Reference&) const = 0; + virtual bool operator<(const Reference&) const = 0; + + virtual ReferencePtr clone() const = 0; + +protected: + + RoutableReference(const InstancePtr&, const ::Ice::Identity&, const ::Ice::Context&, const ::std::string&, + Mode, bool, const RouterInfoPtr&, bool); + RoutableReference(const RoutableReference&); + virtual ~RoutableReference() {} + + +private: + + RouterInfoPtr routerInfo; // Null if no router is used. +}; + +class DirectReference : public RoutableReference +{ +public: + + DirectReference(const InstancePtr&, const ::Ice::Identity&, const ::Ice::Context&, const ::std::string&, Mode, bool, + const ::std::vector<EndpointPtr>&, const RouterInfoPtr&, bool); + + virtual ::std::vector<EndpointPtr> getEndpoints() const; + + DirectReferencePtr changeEndpoints(const ::std::vector<EndpointPtr>&) const; + + virtual ReferencePtr changeCompress(bool) const; + virtual ReferencePtr changeTimeout(int) const; + + virtual void streamWrite(BasicStream*) const; + virtual ::std::string toString() const; + virtual ::Ice::ConnectionIPtr getConnection(bool&) const; + + virtual bool operator==(const Reference&) const; + virtual bool operator!=(const Reference&) const; + virtual bool operator<(const Reference&) const; + + virtual ReferencePtr clone() const; + +protected: + + DirectReference(const DirectReference&); + virtual ~DirectReference() {} + +private: + + ::std::vector<EndpointPtr> endpoints; +}; + +class IndirectReference : public RoutableReference +{ +public: + + IndirectReference(const InstancePtr&, const ::Ice::Identity&, const ::Ice::Context&, const ::std::string&, + Mode, bool, const ::std::string&, const RouterInfoPtr&, const LocatorInfoPtr&, bool); + + const ::std::string& getAdapterId() const { return adapterId; } + const LocatorInfoPtr& getLocatorInfo() const { return locatorInfo; } + + virtual ::std::vector<EndpointPtr> getEndpoints() const; + + IndirectReferencePtr changeAdapterId(const ::std::string&) const; + virtual ReferencePtr changeLocator(const ::Ice::LocatorPrx&) const; + virtual ReferencePtr changeDefault() const; + virtual ReferencePtr changeCompress(bool) const; + virtual ReferencePtr changeTimeout(int) const; + + virtual void streamWrite(BasicStream*) const; + virtual ::std::string toString() const; + virtual ::Ice::ConnectionIPtr getConnection(bool&) const; + + virtual bool operator==(const Reference&) const; + virtual bool operator!=(const Reference&) const; + virtual bool operator<(const Reference&) const; + + virtual ReferencePtr clone() const; + +protected: + + IndirectReference(const IndirectReference&); + virtual ~IndirectReference() {} + +private: + + ::std::string adapterId; + LocatorInfoPtr locatorInfo; // Null if no locator is used. +}; + +::std::vector<EndpointPtr> filterEndpoints(const ::std::vector<EndpointPtr>&, Reference::Mode, bool); + +#if 0 // TODO: move this +class Reference : public ::IceUtil::Shared +{ +public: + + + + // // Filter endpoints or connections based on criteria from this reference. // - std::vector<EndpointPtr> filterEndpoints(const std::vector<EndpointPtr>&) const; - std::vector<Ice::ConnectionIPtr> filterConnections(const std::vector<Ice::ConnectionIPtr>&) const; + ::std::vector<Ice::ConnectionIPtr> filterConnections(const ::std::vector<Ice::ConnectionIPtr>&) const; private: - Reference(const InstancePtr&, const Ice::Identity&, const Ice::Context&, const std::string&, Mode, bool, - const std::string&, const std::vector<EndpointPtr>&, - const RouterInfoPtr&, const LocatorInfoPtr&, const std::vector<Ice::ConnectionIPtr>&, bool); + Reference(const InstancePtr&, const Ice::Identity&, const Ice::Context&, const ::std::string&, Mode, bool, + const ::std::string&, const ::std::vector<EndpointPtr>&, + const RouterInfoPtr&, const LocatorInfoPtr&, const ::std::vector<Ice::ConnectionIPtr>&, bool); friend class ReferenceFactory; }; +#endif } diff --git a/cpp/src/Ice/ReferenceFactory.cpp b/cpp/src/Ice/ReferenceFactory.cpp index 9689cf7bf99..b61f74df323 100644 --- a/cpp/src/Ice/ReferenceFactory.cpp +++ b/cpp/src/Ice/ReferenceFactory.cpp @@ -27,16 +27,32 @@ void IceInternal::incRef(::IceInternal::ReferenceFactory* p) { p->__incRef(); } void IceInternal::decRef(::IceInternal::ReferenceFactory* p) { p->__decRef(); } ReferencePtr +IceInternal::ReferenceFactory::clone(const Reference* r) const +{ + Mutex::Lock sync(*this); + + if(!_instance) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + const Ice::Identity& ident = r->getIdentity(); + if(ident.name.empty() && ident.category.empty()) + { + return 0; + } + + return r->clone(); +} + +ReferencePtr IceInternal::ReferenceFactory::create(const Identity& ident, const Context& context, const string& facet, Reference::Mode mode, bool secure, - const string& adapterId, const vector<EndpointPtr>& endpoints, const RouterInfoPtr& routerInfo, - const LocatorInfoPtr& locatorInfo, - const vector<ConnectionIPtr>& fixedConnections, bool collocationOptimization) { Mutex::Lock sync(*this); @@ -54,70 +70,66 @@ IceInternal::ReferenceFactory::create(const Identity& ident, // // Create new reference // - ReferencePtr ref = new Reference(_instance, ident, context, facet, mode, secure, adapterId, - endpoints, routerInfo, locatorInfo, fixedConnections, - collocationOptimization); + return new DirectReference(_instance, ident, context, facet, mode, secure, + endpoints, routerInfo, collocationOptimization); +} +ReferencePtr +IceInternal::ReferenceFactory::create(const Identity& ident, + const Context& context, + const string& facet, + Reference::Mode mode, + bool secure, + const string& adapterId, + const RouterInfoPtr& routerInfo, + const LocatorInfoPtr& locatorInfo, + bool collocationOptimization) +{ + Mutex::Lock sync(*this); -// -// This code is currently not used, because the eviction code below is -// too slow when there are a large number of references. The savings -// are also rather questionable. -// -/* - // - // If we already have an equivalent reference, use such equivalent - // reference. Otherwise add the new reference to the reference - // set. - // - set<ReferencePtr>::iterator p = _references.end(); - - if(_referencesHint != _references.end()) + if(!_instance) { - if(*_referencesHint == ref) - { - p = _referencesHint; - } + throw CommunicatorDestroyedException(__FILE__, __LINE__); } - - if(p == _references.end()) + + if(ident.name.empty() && ident.category.empty()) { - p = _references.find(ref); + return 0; } - - if(p == _references.end()) + + // + // Create new reference + // + return new IndirectReference(_instance, ident, context, facet, mode, secure, + adapterId, routerInfo, locatorInfo, collocationOptimization); +} + +ReferencePtr +IceInternal::ReferenceFactory::create(const Identity& ident, + const Context& context, + const string& facet, + Reference::Mode mode, + bool secure, + bool collocationOptimization, + const vector<Ice::ConnectionIPtr>& fixedConnections) +{ + Mutex::Lock sync(*this); + + if(!_instance) { - _referencesHint = _references.insert(_referencesHint, ref); + throw CommunicatorDestroyedException(__FILE__, __LINE__); } - else + + if(ident.name.empty() && ident.category.empty()) { - _referencesHint = p; - ref = *_referencesHint; + return 0; } // - // At every 10th call, evict references which are not in use anymore. + // Create new reference // - if(++_evict >= 10) - { - _evict = 0; - p = _references.begin(); - while(p != _references.end()) - { - if((*p)->__getRef() == 1) - { - assert(p != _referencesHint); - _references.erase(p++); - } - else - { - ++p; - } - } - } -*/ - - return ref; + return new FixedReference(_instance, ident, context, facet, mode, secure, + collocationOptimization, fixedConnections); } ReferencePtr @@ -288,7 +300,7 @@ IceInternal::ReferenceFactory::create(const string& str) // // If any new options are added here, - // IceInternal::Reference::toString() must be updated as well. + // IceInternal::Reference::toString() and its derived classes must be updated as well. // switch(option[1]) { @@ -392,10 +404,19 @@ IceInternal::ReferenceFactory::create(const string& str) } } + RouterInfoPtr routerInfo = _instance->routerManager()->get(getDefaultRouter()); + LocatorInfoPtr locatorInfo = _instance->locatorManager()->get(getDefaultLocator()); + + if(beg == string::npos) + { + return create(ident, Context(), facet, mode, secure, "", routerInfo, locatorInfo, true); + } + vector<EndpointPtr> endpoints; - if(beg != string::npos) + + switch(s[beg]) { - if(s[beg] == ':') + case ':': { end = beg; @@ -413,8 +434,10 @@ IceInternal::ReferenceFactory::create(const string& str) EndpointPtr endp = _instance->endpointFactoryManager()->create(es); endpoints.push_back(endp); } + return create(ident, Context(), facet, mode, secure, endpoints, routerInfo, true); + break; } - else if(s[beg] == '@') + case '@': { beg = s.find_first_not_of(delim, beg + 1); if(beg == string::npos) @@ -424,39 +447,42 @@ IceInternal::ReferenceFactory::create(const string& str) throw ex; } - end = IceUtil::checkQuote(s, beg); - if(end == string::npos) - { + end = IceUtil::checkQuote(s, beg); + if(end == string::npos) + { ProxyParseException ex(__FILE__, __LINE__); ex.str = str; throw ex; - } - else if(end == 0) - { - end = s.find_first_of(delim, beg); - if(end == string::npos) - { - end = s.size(); - } - } - else - { - beg++; // Skip leading quote - } + } + else if(end == 0) + { + end = s.find_first_of(delim, beg); + if(end == string::npos) + { + end = s.size(); + } + } + else + { + beg++; // Skip leading quote + } - if(!IceUtil::unescapeString(s, beg, end, adapter) || adapter.size() == 0) - { + if(!IceUtil::unescapeString(s, beg, end, adapter) || adapter.size() == 0) + { ProxyParseException ex(__FILE__, __LINE__); ex.str = str; throw ex; - } + } + return create(ident, Context(), facet, mode, secure, adapter, routerInfo, locatorInfo, true); + break; + } + default: + { + ProxyParseException ex(__FILE__, __LINE__); + ex.str = str; + throw ex; } } - - RouterInfoPtr routerInfo = _instance->routerManager()->get(getDefaultRouter()); - LocatorInfoPtr locatorInfo = _instance->locatorManager()->get(getDefaultLocator()); - return create(ident, Context(), facet, mode, secure, adapter, endpoints, routerInfo, locatorInfo, - vector<ConnectionIPtr>(), true); } ReferencePtr @@ -501,6 +527,9 @@ IceInternal::ReferenceFactory::create(const Identity& ident, BasicStream* s) vector<EndpointPtr> endpoints; string adapterId; + RouterInfoPtr routerInfo = _instance->routerManager()->get(getDefaultRouter()); + LocatorInfoPtr locatorInfo = _instance->locatorManager()->get(getDefaultLocator()); + Ice::Int sz; s->readSize(sz); @@ -512,16 +541,13 @@ IceInternal::ReferenceFactory::create(const Identity& ident, BasicStream* s) EndpointPtr endpoint = _instance->endpointFactoryManager()->read(s); endpoints.push_back(endpoint); } + return create(ident, Context(), facet, mode, secure, endpoints, routerInfo, true); } else { s->read(adapterId); + return create(ident, Context(), facet, mode, secure, adapterId, routerInfo, locatorInfo, true); } - - RouterInfoPtr routerInfo = _instance->routerManager()->get(getDefaultRouter()); - LocatorInfoPtr locatorInfo = _instance->locatorManager()->get(getDefaultLocator()); - return create(ident, Context(), facet, mode, secure, adapterId, endpoints, routerInfo, locatorInfo, - vector<ConnectionIPtr>(), true); } void @@ -553,9 +579,7 @@ IceInternal::ReferenceFactory::getDefaultLocator() const } IceInternal::ReferenceFactory::ReferenceFactory(const InstancePtr& instance) : - _instance(instance), - _referencesHint(_references.end()), - _evict(0) + _instance(instance) { } @@ -572,6 +596,4 @@ IceInternal::ReferenceFactory::destroy() _instance = 0; _defaultRouter = 0; _defaultLocator = 0; - _references.clear(); - _referencesHint = _references.end(); } diff --git a/cpp/src/Ice/ReferenceFactory.h b/cpp/src/Ice/ReferenceFactory.h index 76d1452cc7a..e0bea176a3b 100644 --- a/cpp/src/Ice/ReferenceFactory.h +++ b/cpp/src/Ice/ReferenceFactory.h @@ -14,7 +14,7 @@ #include <IceUtil/Mutex.h> #include <Ice/ReferenceFactoryF.h> #include <Ice/Reference.h> // For Reference::Mode -#include <set> +#include <Ice/ConnectionIF.h> namespace IceInternal { @@ -23,10 +23,37 @@ class ReferenceFactory : public ::IceUtil::Shared, public ::IceUtil::Mutex { public: + // + // Make a polymorphic copy of a reference. + // + ReferencePtr clone(const Reference* r) const; + + // + // Create a direct reference. + // + ReferencePtr create(const Ice::Identity&, const Ice::Context&, const std::string&, + Reference::Mode, bool, const std::vector<EndpointPtr>&, + const RouterInfoPtr&, bool); + // + // Create an indirect reference. + // + ReferencePtr create(const Ice::Identity&, const Ice::Context&, const std::string&, + Reference::Mode, bool, const std::string&, + const RouterInfoPtr&, const LocatorInfoPtr&, bool); + // + // Create a fixed reference. + // ReferencePtr create(const Ice::Identity&, const Ice::Context&, const std::string&, - Reference::Mode, bool, const std::string&, const std::vector<EndpointPtr>&, - const RouterInfoPtr&, const LocatorInfoPtr&, const std::vector<Ice::ConnectionIPtr>&, bool); + Reference::Mode, bool, bool, const std::vector<Ice::ConnectionIPtr>&); + + // + // Create a reference from a string. + // ReferencePtr create(const std::string&); + + // + // Create a reference by unmarshaling it from a stream. + // ReferencePtr create(const Ice::Identity&, BasicStream*); void setDefaultRouter(const ::Ice::RouterPrx&); @@ -44,9 +71,6 @@ private: InstancePtr _instance; Ice::RouterPrx _defaultRouter; Ice::LocatorPrx _defaultLocator; - std::set<ReferencePtr> _references; - std::set<ReferencePtr>::iterator _referencesHint; - int _evict; }; } |