diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/Glacier2/SessionHelper.h | 2 | ||||
-rw-r--r-- | cpp/src/Glacier2Lib/SessionHelper.cpp | 94 | ||||
-rw-r--r-- | cpp/test/Ice/optional/AllTests.cpp | 3 | ||||
-rw-r--r-- | cpp/test/IceGrid/activation/AllTests.cpp | 16 | ||||
-rw-r--r-- | cpp/test/IceGrid/replicaGroup/RegistryPlugin.cpp | 30 |
5 files changed, 89 insertions, 56 deletions
diff --git a/cpp/include/Glacier2/SessionHelper.h b/cpp/include/Glacier2/SessionHelper.h index a61e470354d..00b2bb21914 100644 --- a/cpp/include/Glacier2/SessionHelper.h +++ b/cpp/include/Glacier2/SessionHelper.h @@ -297,7 +297,7 @@ public: private: - void addThread(const SessionHelper*, const IceUtil::ThreadPtr&); + IceUtil::ThreadPtr addThread(const SessionHelper*, const IceUtil::ThreadPtr&); Ice::InitializationData createInitData(); std::string getRouterFinderStr(); diff --git a/cpp/src/Glacier2Lib/SessionHelper.cpp b/cpp/src/Glacier2Lib/SessionHelper.cpp index 7b74c8f17e0..dbd03ce40e4 100644 --- a/cpp/src/Glacier2Lib/SessionHelper.cpp +++ b/cpp/src/Glacier2Lib/SessionHelper.cpp @@ -34,9 +34,9 @@ public: { } - void add(const SessionHelper* session, const IceUtil::ThreadPtr& thread) + IceUtil::ThreadPtr add(const SessionHelper* session, const IceUtil::ThreadPtr& thread) { - _factory->addThread(session, thread); + return _factory->addThread(session, thread); } private: @@ -147,32 +147,31 @@ class DestroyInternal : public IceUtil::Thread public: DestroyInternal(const SessionHelperIPtr& session, - const Glacier2::SessionThreadCallbackPtr& threadCB, - const Glacier2::SessionCallbackPtr& callback) : - _session(session), - _threadCB(threadCB), - _disconnected(new Disconnected(session, callback)) + const Glacier2::SessionCallbackPtr& callback, + const Glacier2::SessionThreadCallbackPtr& threadCB) : + _session(session), _disconnected(new Disconnected(session, callback)) { + _previous = threadCB->add(session.get(), this); } virtual void run() { + _session->destroyInternal(_disconnected); + _session = ICE_NULLPTR; + // - // Add this thread to the factory to ensure it will be jointed on - // destroy. This might join the connection thread so it's important - // to not hold any locks when calling add. + // Join the connect thread to free resources. // - _threadCB->add(_session.get(), this); - _threadCB = 0; - - _session->destroyInternal(_disconnected); - _session = 0; + if(_previous) + { + _previous->getThreadControl().join(); + } } private: SessionHelperIPtr _session; - Glacier2::SessionThreadCallbackPtr _threadCB; + IceUtil::ThreadPtr _previous; const Ice::DispatcherCallPtr _disconnected; }; @@ -181,20 +180,30 @@ class DestroyCommunicator : public IceUtil::Thread public: - DestroyCommunicator(const SessionHelperIPtr& session) : + DestroyCommunicator(const SessionHelperIPtr& session, const Glacier2::SessionThreadCallbackPtr& threadCB) : _session(session) { + _previous = threadCB->add(session.get(), this); } virtual void run() { _session->destroyCommunicator(); - _session = 0; + _session = ICE_NULLPTR; + + // + // Join the connect thread to free resources. + // + if(_previous) + { + _previous->getThreadControl().join(); + } } private: SessionHelperIPtr _session; + IceUtil::ThreadPtr _previous; }; } @@ -224,6 +233,7 @@ SessionHelperI::destroy() } _destroy = true; + IceUtil::ThreadPtr destroyThread; if(!_connected) { // @@ -231,22 +241,20 @@ SessionHelperI::destroy() // We destroy the communicator to trigger the immediate // failure of the connection establishment. // - IceUtil::ThreadPtr destroyCommunicator = new DestroyCommunicator(ICE_SHARED_FROM_THIS); - _threadCB = ICE_NULLPTR; - destroyCommunicator->start(); - return; + destroyThread = new DestroyCommunicator(ICE_SHARED_FROM_THIS, _threadCB); + } + else + { + destroyThread = new DestroyInternal(ICE_SHARED_FROM_THIS, _callback, _threadCB); + _connected = false; + _session = ICE_NULLPTR; } - - IceUtil::ThreadPtr destroyInternal = new DestroyInternal(ICE_SHARED_FROM_THIS, _threadCB, _callback); - - _session = ICE_NULLPTR; - _connected = false; _threadCB = ICE_NULLPTR; // - // Run destroyInternal in a thread because it makes remote invocations. + // Run destroy in a thread because it can block. // - destroyInternal->start(); + destroyThread->start(); } Ice::CommunicatorPtr @@ -941,35 +949,27 @@ Glacier2::SessionFactoryHelper::~SessionFactoryHelper() } } -void +IceUtil::ThreadPtr Glacier2::SessionFactoryHelper::addThread(const SessionHelper* session, const IceUtil::ThreadPtr& thread) { // // A SessionHelper can only ever have one thread running. Therefore any // currently registered thread for the same session must be finished, so - // we just replace it. + // we just replace it. Caller must join returned thread. // + IceUtil::Mutex::Lock sync(_mutex); IceUtil::ThreadPtr previous; + map<const SessionHelper*, IceUtil::ThreadPtr>::iterator p = _threads.find(session); + if(p != _threads.end()) { - IceUtil::Mutex::Lock sync(_mutex); - map<const SessionHelper*, IceUtil::ThreadPtr>::iterator p = _threads.find(session); - if(p != _threads.end()) - { - previous = p->second; - p->second = thread; - } - else - { - _threads.insert(make_pair(session, thread)); - } + previous = p->second; + p->second = thread; } - if(previous) + else { - // - // Join previous thread, joining outside the synchronization is important to prevent deadlocks. - // - previous->getThreadControl().join(); + _threads.insert(make_pair(session, thread)); } + return previous; } void diff --git a/cpp/test/Ice/optional/AllTests.cpp b/cpp/test/Ice/optional/AllTests.cpp index 46e8c717d36..ff23f109af9 100644 --- a/cpp/test/Ice/optional/AllTests.cpp +++ b/cpp/test/Ice/optional/AllTests.cpp @@ -696,6 +696,9 @@ allTests(const Ice::CommunicatorPtr& communicator, bool) // Clear the second half of the optional parameters MultiOptionalPtr mo8 = ICE_MAKE_SHARED(MultiOptional, *mo5); +#ifndef ICE_CPP11_MAPPING + mo8->ice_collectable(true); +#endif mo8->b = IceUtil::None; mo8->d = IceUtil::None; mo8->f = IceUtil::None; diff --git a/cpp/test/IceGrid/activation/AllTests.cpp b/cpp/test/IceGrid/activation/AllTests.cpp index 8ab06b1ea96..c9c2aaa6504 100644 --- a/cpp/test/IceGrid/activation/AllTests.cpp +++ b/cpp/test/IceGrid/activation/AllTests.cpp @@ -447,6 +447,10 @@ allTests(const Ice::CommunicatorPtr& communicator) IceInternal::UniquePtr<Ice::LocalException> ex((*p)->waitUntilFinished()); test(dynamic_cast<Ice::NoEndpointException*>(ex.get())); } + for(p = threads.begin(); p != threads.end(); ++p) + { + (*p)->getThreadControl().join(); + } threads.resize(0); invalid = communicator->stringToProxy("invalid-pwd"); @@ -463,6 +467,10 @@ allTests(const Ice::CommunicatorPtr& communicator) IceInternal::UniquePtr<Ice::LocalException> ex((*p)->waitUntilFinished()); test(dynamic_cast<Ice::NoEndpointException*>(ex.get())); } + for(p = threads.begin(); p != threads.end(); ++p) + { + (*p)->getThreadControl().join(); + } threads.resize(0); invalid = communicator->stringToProxy("fail-on-startup"); @@ -479,6 +487,10 @@ allTests(const Ice::CommunicatorPtr& communicator) IceInternal::UniquePtr<Ice::LocalException> ex((*p)->waitUntilFinished()); test(dynamic_cast<Ice::NoEndpointException*>(ex.get())); } + for(p = threads.begin(); p != threads.end(); ++p) + { + (*p)->getThreadControl().join(); + } threads.resize(0); try @@ -531,6 +543,10 @@ allTests(const Ice::CommunicatorPtr& communicator) IceInternal::UniquePtr<Ice::LocalException> ex((*p)->waitUntilFinished()); test(dynamic_cast<Ice::NoEndpointException*>(ex.get())); } + for(p = threads.begin(); p != threads.end(); ++p) + { + (*p)->getThreadControl().join(); + } admin->stopServer("server-activation-timeout"); } catch(const IceGrid::ServerStopException& ex) diff --git a/cpp/test/IceGrid/replicaGroup/RegistryPlugin.cpp b/cpp/test/IceGrid/replicaGroup/RegistryPlugin.cpp index a177c0cfbe2..434293ee7b8 100644 --- a/cpp/test/IceGrid/replicaGroup/RegistryPlugin.cpp +++ b/cpp/test/IceGrid/replicaGroup/RegistryPlugin.cpp @@ -30,6 +30,10 @@ public: private: const Ice::CommunicatorPtr _communicator; + ReplicaGroupFilterPtr _filterByServer; + ReplicaGroupFilterPtr _excludeServer2; + ReplicaGroupFilterPtr _excludeServer3; + TypeFilterPtr _type; }; class ReplicaGroupFilterI : public IceGrid::ReplicaGroupFilter @@ -176,19 +180,29 @@ RegistryPluginI::initialize() IceGrid::RegistryPluginFacadePtr facade = IceGrid::getRegistryPluginFacade(); assert(facade); - ReplicaGroupFilterPtr f = new ReplicaGroupFilterI(facade); - facade->addReplicaGroupFilter("filterByServer", f); - test(facade->removeReplicaGroupFilter("filterByServer", f)); - test(!facade->removeReplicaGroupFilter("filterByServer", f)); + _filterByServer = new ReplicaGroupFilterI(facade); + _excludeServer2 = new ExcludeReplicaGroupFilterI(facade, "Server2"); + _excludeServer3 = new ExcludeReplicaGroupFilterI(facade, "Server3"); + _type = new TypeFilterI(facade); - facade->addReplicaGroupFilter("filterByServer", f); - facade->addReplicaGroupFilter("excludeServer", new ExcludeReplicaGroupFilterI(facade, "Server2")); - facade->addReplicaGroupFilter("excludeServer", new ExcludeReplicaGroupFilterI(facade, "Server3")); + facade->addReplicaGroupFilter("filterByServer", _filterByServer); + test(facade->removeReplicaGroupFilter("filterByServer", _filterByServer)); + test(!facade->removeReplicaGroupFilter("filterByServer", _filterByServer)); - facade->addTypeFilter("::Test::TestIntf2", new TypeFilterI(facade)); + facade->addReplicaGroupFilter("filterByServer", _filterByServer); + facade->addReplicaGroupFilter("excludeServer", _excludeServer2); + facade->addReplicaGroupFilter("excludeServer", _excludeServer3); + facade->addTypeFilter("::Test::TestIntf2", _type); } void RegistryPluginI::destroy() { + IceGrid::RegistryPluginFacadePtr facade = IceGrid::getRegistryPluginFacade(); + assert(facade); + + facade->removeReplicaGroupFilter("filterByServer", _filterByServer); + facade->removeReplicaGroupFilter("excludeServer", _excludeServer2); + facade->removeReplicaGroupFilter("excludeServer", _excludeServer3); + facade->removeTypeFilter("::Test::TestIntf2", _type); } |