summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Glacier2/SessionHelper.h2
-rw-r--r--cpp/src/Glacier2Lib/SessionHelper.cpp94
-rw-r--r--cpp/test/Ice/optional/AllTests.cpp3
-rw-r--r--cpp/test/IceGrid/activation/AllTests.cpp16
-rw-r--r--cpp/test/IceGrid/replicaGroup/RegistryPlugin.cpp30
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);
}