summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Ice/ObjectAdapterFactory.cpp30
-rw-r--r--cpp/src/Ice/ObjectAdapterFactory.h1
-rw-r--r--cpp/src/Ice/ObjectAdapterI.cpp59
-rw-r--r--cpp/src/Ice/ObjectAdapterI.h2
4 files changed, 63 insertions, 29 deletions
diff --git a/cpp/src/Ice/ObjectAdapterFactory.cpp b/cpp/src/Ice/ObjectAdapterFactory.cpp
index 1fc6e3d88f4..54f673efa65 100644
--- a/cpp/src/Ice/ObjectAdapterFactory.cpp
+++ b/cpp/src/Ice/ObjectAdapterFactory.cpp
@@ -67,15 +67,6 @@ IceInternal::ObjectAdapterFactory::waitForShutdown()
wait();
}
- //
- // If some other thread is currently shutting down, we wait
- // until this thread is finished.
- //
- while(_waitForShutdown)
- {
- wait();
- }
- _waitForShutdown = true;
adapters = _adapters;
}
@@ -83,16 +74,6 @@ IceInternal::ObjectAdapterFactory::waitForShutdown()
// Now we wait for deactivation of each object adapter.
//
for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(&ObjectAdapter::waitForDeactivate));
-
- {
- IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
-
- //
- // Signal that waiting is complete.
- //
- _waitForShutdown = false;
- notifyAll();
- }
}
bool
@@ -115,13 +96,18 @@ IceInternal::ObjectAdapterFactory::destroy()
{
IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
- adapters.swap(_adapters);
+ adapters = _adapters;
}
//
// Now we destroy each object adapter.
//
for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(&ObjectAdapter::destroy));
+
+ {
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+ _adapters.clear();
+ }
}
ObjectAdapterPtr
@@ -223,8 +209,7 @@ IceInternal::ObjectAdapterFactory::flushBatchRequests() const
IceInternal::ObjectAdapterFactory::ObjectAdapterFactory(const InstancePtr& instance,
const CommunicatorPtr& communicator) :
_instance(instance),
- _communicator(communicator),
- _waitForShutdown(false)
+ _communicator(communicator)
{
}
@@ -233,5 +218,4 @@ IceInternal::ObjectAdapterFactory::~ObjectAdapterFactory()
assert(!_instance);
assert(!_communicator);
assert(_adapters.empty());
- assert(!_waitForShutdown);
}
diff --git a/cpp/src/Ice/ObjectAdapterFactory.h b/cpp/src/Ice/ObjectAdapterFactory.h
index 0423522ca3d..e0c7e30ebee 100644
--- a/cpp/src/Ice/ObjectAdapterFactory.h
+++ b/cpp/src/Ice/ObjectAdapterFactory.h
@@ -43,7 +43,6 @@ private:
::Ice::CommunicatorPtr _communicator;
std::set<std::string> _adapterNamesInUse;
std::list<Ice::ObjectAdapterIPtr> _adapters;
- bool _waitForShutdown;
};
}
diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp
index 2e6dfa913b3..6f3081d7ae6 100644
--- a/cpp/src/Ice/ObjectAdapterI.cpp
+++ b/cpp/src/Ice/ObjectAdapterI.cpp
@@ -72,6 +72,13 @@ Ice::ObjectAdapterI::activate()
checkForDeactivation();
//
+ // If some threads are waiting on waitForHold(), we set this
+ // flag to ensure the threads will start again the wait for
+ // all the incoming connection factories.
+ //
+ _waitForHoldRetry = _waitForHold > 0;
+
+ //
// If the one off initializations of the adapter are already
// done, we just need to activate the incoming connection
// factories and we're done.
@@ -158,12 +165,52 @@ Ice::ObjectAdapterI::hold()
void
Ice::ObjectAdapterI::waitForHold()
{
- IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
-
- checkForDeactivation();
+ while(true)
+ {
+ vector<IncomingConnectionFactoryPtr> incomingConnectionFactories;
+ {
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ checkForDeactivation();
+
+ incomingConnectionFactories = _incomingConnectionFactories;
- for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(),
- Ice::constVoidMemFun(&IncomingConnectionFactory::waitUntilHolding));
+ ++_waitForHold;
+ }
+
+ for_each(incomingConnectionFactories.begin(), incomingConnectionFactories.end(),
+ Ice::constVoidMemFun(&IncomingConnectionFactory::waitUntilHolding));
+
+ {
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+ if(--_waitForHold == 0)
+ {
+ notifyAll();
+ }
+
+ //
+ // If we don't need to retry, we're done. Otherwise, we wait until
+ // all the waiters finish waiting on the connections and we try
+ // again waiting on all the conncetions. This is necessary in the
+ // case activate() is called by another thread while waitForHold()
+ // waits on the some connection, if we didn't retry, waitForHold()
+ // could return only after waiting on a subset of the connections.
+ //
+ if(!_waitForHoldRetry)
+ {
+ return;
+ }
+ else
+ {
+ while(_waitForHold > 0)
+ {
+ checkForDeactivation();
+ wait();
+ }
+ _waitForHoldRetry = false;
+ }
+ }
+ }
}
void
@@ -795,6 +842,8 @@ Ice::ObjectAdapterI::ObjectAdapterI(const InstancePtr& instance, const Communica
_name(name),
_directCount(0),
_waitForActivate(false),
+ _waitForHold(0),
+ _waitForHoldRetry(false),
_destroying(false),
_destroyed(false),
_noConfig(noConfig)
diff --git a/cpp/src/Ice/ObjectAdapterI.h b/cpp/src/Ice/ObjectAdapterI.h
index 201be76287d..13866ba7f7e 100644
--- a/cpp/src/Ice/ObjectAdapterI.h
+++ b/cpp/src/Ice/ObjectAdapterI.h
@@ -129,6 +129,8 @@ private:
IceInternal::LocatorInfoPtr _locatorInfo;
int _directCount; // The number of direct proxies dispatching on this object adapter.
bool _waitForActivate;
+ int _waitForHold;
+ bool _waitForHoldRetry;
bool _destroying;
bool _destroyed;
bool _noConfig;