diff options
author | Benoit Foucher <benoit@zeroc.com> | 2006-06-16 14:12:35 +0000 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2006-06-16 14:12:35 +0000 |
commit | 8d9e22b943989bf90012ee811111997ef5d202d7 (patch) | |
tree | 038ac7ef84b6e52038f4d3daa2aa6eb19f2c39b8 /cppe/src/IceE/ObjectAdapter.cpp | |
parent | Fixed bug 1077, 1002. (diff) | |
download | ice-8d9e22b943989bf90012ee811111997ef5d202d7.tar.bz2 ice-8d9e22b943989bf90012ee811111997ef5d202d7.tar.xz ice-8d9e22b943989bf90012ee811111997ef5d202d7.zip |
Fixed bug 1002, 1077.
Diffstat (limited to 'cppe/src/IceE/ObjectAdapter.cpp')
-rw-r--r-- | cppe/src/IceE/ObjectAdapter.cpp | 213 |
1 files changed, 149 insertions, 64 deletions
diff --git a/cppe/src/IceE/ObjectAdapter.cpp b/cppe/src/IceE/ObjectAdapter.cpp index d97c8176c8d..012d5a16b52 100644 --- a/cppe/src/IceE/ObjectAdapter.cpp +++ b/cppe/src/IceE/ObjectAdapter.cpp @@ -98,79 +98,53 @@ Ice::ObjectAdapter::activate() checkForDeactivation(); - if(!_printAdapterReadyDone) + // + // If the one off initializations of the adapter are already + // done, we just need to activate the incoming connection + // factories and we're done. + // + if(_activateOneOffDone) { + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + Ice::voidMemFun(&IncomingConnectionFactory::activate)); + return; + } + + // + // One off initializations of the adapter: update the locator + // registry and print the "adapter ready" message. We set the + // _waitForActivate flag to prevent deactivation from other + // threads while these one off initializations are done. + // + _waitForActivate = true; + #ifdef ICEE_HAS_LOCATOR - locatorInfo = _locatorInfo; + locatorInfo = _locatorInfo; #endif - printAdapterReady = - _instance->initializationData().properties->getPropertyAsInt("Ice.PrintAdapterReady") > 0; - _printAdapterReadyDone = true; - } - - for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), - Ice::voidMemFun(&IncomingConnectionFactory::activate)); + printAdapterReady = _instance->initializationData().properties->getPropertyAsInt("Ice.PrintAdapterReady") > 0; } #ifdef ICEE_HAS_LOCATOR - if(!_id.empty()) + try + { + Ice::Identity dummy; + dummy.name = "dummy"; + updateLocatorRegistry(locatorInfo, createDirectProxy(dummy)); + } + catch(const Ice::LocalException&) { // - // We must call on the locator registry outside the thread - // synchronization, to avoid deadlocks. + // If we couldn't update the locator registry, we let the + // exception go through and don't activate the adapter to + // allow to user code to retry activating the adapter + // later. // - LocatorRegistryPrx locatorRegistry; - if(locatorInfo) - { - // - // TODO: This might throw if we can't connect to the - // locator. Shall we raise a special exception for the - // activate operation instead of a non obvious network - // exception? - // - locatorRegistry = locatorInfo->getLocatorRegistry(); - } - - if(locatorRegistry) { - try - { - Identity ident; - ident.name = "dummy"; - if(_replicaGroupId.empty()) - { - locatorRegistry->setAdapterDirectProxy(_id, createDirectProxy(ident)); - } - else - { - locatorRegistry->setReplicatedAdapterDirectProxy(_id, _replicaGroupId, createDirectProxy(ident)); - } - } - catch(const ObjectAdapterDeactivatedException&) - { - // IGNORE: The object adapter is already inactive. - } - catch(const AdapterNotFoundException&) - { - NotRegisteredException ex(__FILE__, __LINE__); - ex.kindOfObject = "object adapter"; - ex.id = _id; - throw ex; - } - catch(const InvalidReplicaGroupIdException&) - { - NotRegisteredException ex(__FILE__, __LINE__); - ex.kindOfObject = "replica group"; - ex.id = _replicaGroupId; - throw ex; - } - catch(const AdapterAlreadyActiveException&) - { - ObjectAdapterIdInUseException ex(__FILE__, __LINE__); - ex.id = _id; - throw ex; - } + IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); + _waitForActivate = false; + notifyAll(); } + throw; } #endif @@ -179,6 +153,22 @@ Ice::ObjectAdapter::activate() printf("%s ready\n", _name.c_str()); fflush(stdout); } + + { + IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); + assert(!_deactivated); // Not possible if _waitForActivate = true; + + // + // Signal threads waiting for the activation. + // + _waitForActivate = false; + notifyAll(); + + _activateOneOffDone = true; + + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + Ice::voidMemFun(&IncomingConnectionFactory::activate)); + } } void @@ -208,6 +198,9 @@ Ice::ObjectAdapter::deactivate() { vector<IncomingConnectionFactoryPtr> incomingConnectionFactories; OutgoingConnectionFactoryPtr outgoingConnectionFactory; +#ifdef ICEE_HAS_LOCATOR + LocatorInfoPtr locatorInfo; +#endif { IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); @@ -221,6 +214,16 @@ Ice::ObjectAdapter::deactivate() return; } + // + // Wait for activation to complete. This is necessary to not + // get out of order locator updates. + // + while(_waitForActivate) + { + wait(); + } + + #ifdef ICEE_HAS_ROUTER if(_routerInfo) { @@ -238,12 +241,29 @@ Ice::ObjectAdapter::deactivate() incomingConnectionFactories = _incomingConnectionFactories; outgoingConnectionFactory = _instance->outgoingConnectionFactory(); - +#ifdef ICEE_HAS_LOCATOR + locatorInfo = _locatorInfo; +#endif + _deactivated = true; notifyAll(); } +#ifdef ICEE_HAS_LOCATOR + try + { + updateLocatorRegistry(locatorInfo, 0); + } + catch(const Ice::LocalException&) + { + // + // We can't throw exceptions in deactivate so we ignore + // failures to update the locator registry. + // + } +#endif + // // Must be called outside the thread synchronization, because // Connection::destroy() might block when sending a CloseConnection @@ -575,13 +595,14 @@ Ice::ObjectAdapter::ObjectAdapter(const InstancePtr& instance, const Communicato _communicator(communicator), _objectAdapterFactory(objectAdapterFactory), _servantManager(new ServantManager(instance, name)), - _printAdapterReadyDone(false), + _activateOneOffDone(false), _name(name), #ifdef ICEE_HAS_LOCATOR _id(instance->initializationData().properties->getProperty(name + ".AdapterId")), _replicaGroupId(instance->initializationData().properties->getProperty(name + ".ReplicaGroupId")), #endif _directCount(0), + _waitForActivate(false), _waitForDeactivate(false) { __setNoDelete(true); @@ -710,6 +731,7 @@ Ice::ObjectAdapter::~ObjectAdapter() assert(!_communicator); assert(_incomingConnectionFactories.empty()); assert(_directCount == 0); + assert(!_waitForActivate); assert(!_waitForDeactivate); } } @@ -856,3 +878,66 @@ Ice::ObjectAdapter::parseEndpoints(const string& str) const return endpoints; } + +#ifdef ICEE_HAS_LOCATOR +void +ObjectAdapter::updateLocatorRegistry(const IceInternal::LocatorInfoPtr& locatorInfo, const Ice::ObjectPrx& proxy) +{ + if(_id.empty()) + { + return; // Nothing to update. + } + + // + // We must get and call on the locator registry outside the thread + // synchronization to avoid deadlocks. (we can't make remote calls + // within the OA synchronization because the remote call will + // indirectly call isLocal() on this OA with the OA factory + // locked). + // + // TODO: This might throw if we can't connect to the + // locator. Shall we raise a special exception for the activate + // operation instead of a non obvious network exception? + // + LocatorRegistryPrx locatorRegistry = locatorInfo ? locatorInfo->getLocatorRegistry() : LocatorRegistryPrx(); + if(!locatorRegistry) + { + return; + } + + if(!_id.empty()) + { + try + { + if(_replicaGroupId.empty()) + { + locatorRegistry->setAdapterDirectProxy(_id, proxy); + } + else + { + locatorRegistry->setReplicatedAdapterDirectProxy(_id, _replicaGroupId, proxy); + } + } + catch(const AdapterNotFoundException&) + { + NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "object adapter"; + ex.id = _id; + throw ex; + } + catch(const InvalidReplicaGroupIdException&) + { + NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "replica group"; + ex.id = _replicaGroupId; + throw ex; + } + catch(const AdapterAlreadyActiveException&) + { + ObjectAdapterIdInUseException ex(__FILE__, __LINE__); + ex.id = _id; + throw ex; + } + } +} +#endif |