fix Thread::exit/Thread::dispose race condition

There was a race between these two functions such that one thread A
would run dispose on thread B just before thread B finishes exit, with
the result that Thread::lock and/or Thread::systemThread would be
disposed twice, resulting in a crash.
This commit is contained in:
Joel Dice 2011-02-28 10:14:01 -07:00
parent 255fc9f9d3
commit 25f1a9f1e8
2 changed files with 15 additions and 9 deletions

View File

@ -2413,20 +2413,23 @@ Thread::exit()
} else { } else {
threadPeer(this, javaThread) = 0; threadPeer(this, javaThread) = 0;
System::Monitor* myLock = lock;
System::Thread* mySystemThread = systemThread;
{ ACQUIRE_RAW(this, m->stateLock); { ACQUIRE_RAW(this, m->stateLock);
while (flags & SystemFlag) { while (flags & SystemFlag) {
m->stateLock->wait(systemThread, 0); m->stateLock->wait(systemThread, 0);
} }
atomicOr(&flags, Thread::DisposeFlag);
enter(this, Thread::ZombieState); enter(this, Thread::ZombieState);
} }
lock->dispose(); myLock->dispose();
lock = 0;
systemThread->dispose(); mySystemThread->dispose();
systemThread = 0;
} }
} }
} }
@ -2434,12 +2437,14 @@ Thread::exit()
void void
Thread::dispose() Thread::dispose()
{ {
if (lock) { if ((flags & Thread::DisposeFlag) == 0) {
lock->dispose(); if (lock) {
} lock->dispose();
}
if (systemThread) { if (systemThread) {
systemThread->dispose(); systemThread->dispose();
}
} }
m->heap->free(defaultHeap, ThreadHeapSizeInBytes); m->heap->free(defaultHeap, ThreadHeapSizeInBytes);

View File

@ -1369,6 +1369,7 @@ class Thread {
static const unsigned StressFlag = 1 << 4; static const unsigned StressFlag = 1 << 4;
static const unsigned ActiveFlag = 1 << 5; static const unsigned ActiveFlag = 1 << 5;
static const unsigned SystemFlag = 1 << 6; static const unsigned SystemFlag = 1 << 6;
static const unsigned DisposeFlag = 1 << 7;
class Protector { class Protector {
public: public: