summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2004-03-24 05:18:18 +0000
committerMichi Henning <michi@zeroc.com>2004-03-24 05:18:18 +0000
commitabc9df1d86f7d351b6257e4bfd435895ac408cb9 (patch)
treef5a59616ad0b00539d46d8140aa1da4fd1123c2c /cpp/src
parentRemoved reference to Xerces-C. (diff)
downloadice-abc9df1d86f7d351b6257e4bfd435895ac408cb9.tar.bz2
ice-abc9df1d86f7d351b6257e4bfd435895ac408cb9.tar.xz
ice-abc9df1d86f7d351b6257e4bfd435895ac408cb9.zip
Added a comment to GCShared to explain why delete is called by __decRef()
outside the protection of the lock. Also moved the code to update the object set from ~GCShared() to the garbage collector. That's cleaner than doing it from the destructor.
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/IceUtil/GC.cpp1
-rw-r--r--cpp/src/IceUtil/GCShared.cpp9
2 files changed, 7 insertions, 3 deletions
diff --git a/cpp/src/IceUtil/GC.cpp b/cpp/src/IceUtil/GC.cpp
index cd8b23a4298..148a85fb878 100644
--- a/cpp/src/IceUtil/GC.cpp
+++ b/cpp/src/IceUtil/GC.cpp
@@ -229,6 +229,7 @@ IceUtil::GC::collectGarbage()
}
for(i = counts.begin(); i != counts.end(); ++i)
{
+ gcObjects.erase(i->first);
delete i->first;
if(_statsCallback)
{
diff --git a/cpp/src/IceUtil/GCShared.cpp b/cpp/src/IceUtil/GCShared.cpp
index 5a92cdaeb76..b3828475481 100644
--- a/cpp/src/IceUtil/GCShared.cpp
+++ b/cpp/src/IceUtil/GCShared.cpp
@@ -29,9 +29,6 @@ IceUtil::GCShared::GCShared()
IceUtil::GCShared::~GCShared()
{
- gcRecMutex._m->lock();
- gcObjects.erase(this);
- gcRecMutex._m->unlock();
}
void
@@ -71,6 +68,12 @@ IceUtil::GCShared::__decRef()
}
gcRecMutex._m->unlock();
+ //
+ // We call delete outside the lock to avoid deadlock: if thread 1 executes
+ // the destructor of a class, and the destructor tries to join with thread 2,
+ // we would deadlock if thread 2 can't complete until after it has destroyed
+ // some class instance of its own.
+ //
if(doDelete)
{
delete this;