summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/ServantManager.cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2004-05-20 19:52:04 +0000
committerBernard Normier <bernard@zeroc.com>2004-05-20 19:52:04 +0000
commitab6b7d91a0d4f27a9f1a289e7a95f653de03a248 (patch)
tree27eea95a640587461acd87ef489615e5718a481e /cpp/src/Ice/ServantManager.cpp
parentFixed strange Sun CC 5.5 release failure (diff)
downloadice-ab6b7d91a0d4f27a9f1a289e7a95f653de03a248.tar.bz2
ice-ab6b7d91a0d4f27a9f1a289e7a95f653de03a248.tar.xz
ice-ab6b7d91a0d4f27a9f1a289e7a95f653de03a248.zip
remove now returns the servant
Diffstat (limited to 'cpp/src/Ice/ServantManager.cpp')
-rw-r--r--cpp/src/Ice/ServantManager.cpp80
1 files changed, 51 insertions, 29 deletions
diff --git a/cpp/src/Ice/ServantManager.cpp b/cpp/src/Ice/ServantManager.cpp
index 0f926568a7e..4030dd8bf31 100644
--- a/cpp/src/Ice/ServantManager.cpp
+++ b/cpp/src/Ice/ServantManager.cpp
@@ -60,9 +60,16 @@ IceInternal::ServantManager::addServant(const ObjectPtr& object, const Identity&
p->second.insert(pair<const string, ObjectPtr>(facet, object));
}
-void
+ObjectPtr
IceInternal::ServantManager::removeServant(const Identity& ident, const string& facet)
{
+ //
+ // We return the removed servant to avoid releasing the last reference count
+ // with *this locked. We don't want to run user code, such as the servant
+ // destructor, with an internal Ice mutex locked.
+ //
+ ObjectPtr servant = 0;
+
IceUtil::Mutex::Lock sync(*this);
assert(_instance); // Must not be called after destruction.
@@ -87,6 +94,7 @@ IceInternal::ServantManager::removeServant(const Identity& ident, const string&
throw ex;
}
+ servant = q->second;
p->second.erase(q);
if(p->second.empty())
@@ -101,6 +109,7 @@ IceInternal::ServantManager::removeServant(const Identity& ident, const string&
_servantMapMap.erase(p);
}
}
+ return servant;
}
FacetMap
@@ -297,38 +306,51 @@ IceInternal::ServantManager::~ServantManager()
void
IceInternal::ServantManager::destroy()
{
- IceUtil::Mutex::Lock sync(*this);
-
- assert(_instance); // Must not be called after destruction.
-
- _servantMapMap.clear();
- _servantMapMapHint = _servantMapMap.end();
+ ServantMapMap servantMapMap;
+ map<string, ServantLocatorPtr> locatorMap;
- for(map<string, ServantLocatorPtr>::const_iterator p = _locatorMap.begin(); p != _locatorMap.end(); ++p)
{
- try
- {
- p->second->deactivate(p->first);
- }
- catch(const Exception& ex)
+ IceUtil::Mutex::Lock sync(*this);
+
+ assert(_instance); // Must not be called after destruction.
+
+ servantMapMap.swap(_servantMapMap);
+ _servantMapMapHint = _servantMapMap.end();
+
+ for(map<string, ServantLocatorPtr>::const_iterator p = _locatorMap.begin(); p != _locatorMap.end(); ++p)
{
- Error out(_instance->logger());
- out << "exception during locator deactivation:\n"
- << "object adapter: `" << _adapterName << "'\n"
- << "locator category: `" << p->first << "'\n"
- << ex;
- }
- catch(...)
- {
- Error out(_instance->logger());
- out << "unknown exception during locator deactivation:\n"
- << "object adapter: `" << _adapterName << "'\n"
- << "locator category: `" << p->first << "'";
+ try
+ {
+ p->second->deactivate(p->first);
+ }
+ catch(const Exception& ex)
+ {
+ Error out(_instance->logger());
+ out << "exception during locator deactivation:\n"
+ << "object adapter: `" << _adapterName << "'\n"
+ << "locator category: `" << p->first << "'\n"
+ << ex;
+ }
+ catch(...)
+ {
+ Error out(_instance->logger());
+ out << "unknown exception during locator deactivation:\n"
+ << "object adapter: `" << _adapterName << "'\n"
+ << "locator category: `" << p->first << "'";
+ }
}
+
+ locatorMap.swap(_locatorMap);
+ _locatorMapHint = _locatorMap.end();
+
+ _instance = 0;
}
- _locatorMap.clear();
- _locatorMapHint = _locatorMap.end();
-
- _instance = 0;
+ //
+ // We clear the maps outside the synchronization as we don't want to
+ // hold any internal Ice mutex while running user code (such as servant
+ // or servant locator destructors).
+ //
+ servantMapMap.clear();
+ locatorMap.clear();
}