diff options
author | Benoit Foucher <benoit@zeroc.com> | 2018-02-16 12:36:36 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2018-02-16 12:36:36 +0100 |
commit | 1d9509c347547b2d36d6fa3ff667927836d72245 (patch) | |
tree | df6cc4ac9d1e2742ae8d9bf36a4f7927e7f970c1 /cpp/src/Ice/ObjectAdapterFactory.cpp | |
parent | Allow to create NuGet packages with single platform/configuration (diff) | |
download | ice-1d9509c347547b2d36d6fa3ff667927836d72245.tar.bz2 ice-1d9509c347547b2d36d6fa3ff667927836d72245.tar.xz ice-1d9509c347547b2d36d6fa3ff667927836d72245.zip |
Improved object adapter getPublishedEndpoints/refreshPublishedEndpoints method
to return the Ice router server endpoints if the adapter is associated with a
router.
setPublishedEndpoints now also raises an invalid argument exception for such
adapters.
Also fixed a rare deadlock that could occur on adapter creating if the router
wasn't accessible.
Fixes ICE-8675 and ICE-8650
Diffstat (limited to 'cpp/src/Ice/ObjectAdapterFactory.cpp')
-rw-r--r-- | cpp/src/Ice/ObjectAdapterFactory.cpp | 70 |
1 files changed, 52 insertions, 18 deletions
diff --git a/cpp/src/Ice/ObjectAdapterFactory.cpp b/cpp/src/Ice/ObjectAdapterFactory.cpp index 69fbc13aa2c..12de90e3212 100644 --- a/cpp/src/Ice/ObjectAdapterFactory.cpp +++ b/cpp/src/Ice/ObjectAdapterFactory.cpp @@ -41,8 +41,8 @@ IceInternal::ObjectAdapterFactory::shutdown() adapters = _adapters; - _instance = 0; - _communicator = 0; + _instance = ICE_NULLPTR; + _communicator = ICE_NULLPTR; notifyAll(); } @@ -147,32 +147,66 @@ IceInternal::ObjectAdapterFactory::updateObservers(void (ObjectAdapterI::*fn)()) ObjectAdapterPtr IceInternal::ObjectAdapterFactory::createObjectAdapter(const string& name, const RouterPrxPtr& router) { - IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); - - if(!_instance) + ObjectAdapterIPtr adapter; { - throw CommunicatorDestroyedException(__FILE__, __LINE__); + IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); + + if(!_instance) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(name.empty()) + { + string uuid = Ice::generateUUID(); + adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, uuid, true); + } + else + { + if(_adapterNamesInUse.find(name) != _adapterNamesInUse.end()) + { + throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter", name); + } + adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, name, false); + _adapterNamesInUse.insert(name); + } } - ObjectAdapterIPtr adapter; - if(name.empty()) + // + // Must be called outside the synchronization since initialize can make client invocations + // on the router if it's set. + // + bool initialized = false; + try { - string uuid = Ice::generateUUID(); - adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, uuid, true); - adapter->initialize(ICE_NULLPTR); + adapter->initialize(router); + initialized = true; + + IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); + if(!_instance) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + _adapters.push_back(adapter); } - else + catch(const Ice::CommunicatorDestroyedException&) { - if(_adapterNamesInUse.find(name) != _adapterNamesInUse.end()) + if(initialized) { - throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter", name); + adapter->destroy(); } - adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, name, false); - adapter->initialize(router); - _adapterNamesInUse.insert(name); + throw; + } + catch(const std::exception&) + { + if(!name.empty()) + { + IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); + _adapterNamesInUse.erase(name); + } + throw; } - _adapters.push_back(adapter); return adapter; } |