summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2004-01-12 04:38:30 +0000
committerMichi Henning <michi@zeroc.com>2004-01-12 04:38:30 +0000
commit46c8f31b3177a15629b9e609da574893b13eaaf7 (patch)
treedf5b30a96608f010a058138ea1244dd59b21e788 /cpp/src
parentAdded missing initializer for the local variable "promote" in (diff)
downloadice-46c8f31b3177a15629b9e609da574893b13eaaf7.tar.bz2
ice-46c8f31b3177a15629b9e609da574893b13eaaf7.tar.xz
ice-46c8f31b3177a15629b9e609da574893b13eaaf7.zip
Fixed a race condition that could lead to deadlock of a thread tried to
join with another thread from within the destructor of a servant or class.
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/IceUtil/GCShared.cpp23
1 files changed, 10 insertions, 13 deletions
diff --git a/cpp/src/IceUtil/GCShared.cpp b/cpp/src/IceUtil/GCShared.cpp
index 1d50d864d70..51705f7a655 100644
--- a/cpp/src/IceUtil/GCShared.cpp
+++ b/cpp/src/IceUtil/GCShared.cpp
@@ -20,23 +20,14 @@ using namespace IceUtil;
IceUtil::GCObjectSet IceUtil::gcObjects;
IceUtil::GCShared::GCShared()
+ : _ref(0), _noDelete(false)
{
- gcRecMutex._m->lock();
- _ref = 0;
- _noDelete = false;
- _adopted = false;
- gcRecMutex._m->unlock();
}
IceUtil::GCShared::~GCShared()
{
gcRecMutex._m->lock();
-#ifdef NDEBUG // To avoid annoying warnings about variables that are not used...
gcObjects.erase(this);
-#else
- GCObjectSet::size_type num = gcObjects.erase(this);
- assert(num == 1 || !_adopted);
-#endif
gcRecMutex._m->unlock();
}
@@ -45,9 +36,8 @@ IceUtil::GCShared::__incRef()
{
gcRecMutex._m->lock();
assert(_ref >= 0);
- if(!_adopted && _ref == 0)
+ if(_ref == 0)
{
- _adopted = true;
#ifdef NDEBUG // To avoid annoying warnings about variables that are not used...
gcObjects.insert(this);
#else
@@ -69,12 +59,19 @@ IceUtil::GCShared::__decRef()
{
doDelete = !_noDelete;
_noDelete = true;
+#ifdef NDEBUG // To avoid annoying warnings about variables that are not used...
+ gcObjects.erase(this);
+#else
+ GCObjectSet::size_type num = gcObjects.erase(this);
+ assert(num == 1);
+#endif
}
+ gcRecMutex._m->unlock();
+
if(doDelete)
{
delete this;
}
- gcRecMutex._m->unlock();
}
int