diff options
author | Michi Henning <michi@zeroc.com> | 2004-01-12 04:38:30 +0000 |
---|---|---|
committer | Michi Henning <michi@zeroc.com> | 2004-01-12 04:38:30 +0000 |
commit | 46c8f31b3177a15629b9e609da574893b13eaaf7 (patch) | |
tree | df5b30a96608f010a058138ea1244dd59b21e788 /cpp | |
parent | Added missing initializer for the local variable "promote" in (diff) | |
download | ice-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')
-rw-r--r-- | cpp/CHANGES | 4 | ||||
-rw-r--r-- | cpp/include/IceUtil/GCShared.h | 1 | ||||
-rw-r--r-- | cpp/src/IceUtil/GCShared.cpp | 23 |
3 files changed, 14 insertions, 14 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES index c2920f08b95..ad483c0ef25 100644 --- a/cpp/CHANGES +++ b/cpp/CHANGES @@ -1,6 +1,10 @@ Changes since version 1.2.0 --------------------------- +- Fixed a race condition that could lead to a deadlock if + a thread tried to join with another thread from within + the destructor of a servant or class. + - Added support for IcePack and Glacier on Windows platforms. The IcePack Registry, IcePack Node and Glacier Starter programs can optionally be installed as Windows services. See the Ice diff --git a/cpp/include/IceUtil/GCShared.h b/cpp/include/IceUtil/GCShared.h index b83598d584b..54151640dd9 100644 --- a/cpp/include/IceUtil/GCShared.h +++ b/cpp/include/IceUtil/GCShared.h @@ -51,7 +51,6 @@ private: int _ref; bool _noDelete; - bool _adopted; friend class IceUtil::GC; }; 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 |