diff --git a/src/machine.cpp b/src/machine.cpp index c9026e5360..73de8e32d3 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -45,18 +45,10 @@ void join(Thread* t, Thread* o) { if (t != o) { - // todo: There's potentially a leak here on systems where we must - // call join on a thread in order to clean up all resources - // associated with it. If a thread has already been zombified by - // the time we get here, acquireSystem will return false, which - // means we can't safely join it because the System::Thread may - // already have been disposed. In that case, the thread has - // already exited (or will soon), but the OS will never free all - // its resources because it doesn't know we're completely done - // with it. - if (acquireSystem(t, o)) { + assert(t, o->state != Thread::JoinedState); + assert(t, (o->flags & Thread::SystemFlag) == 0); + if (o->flags & Thread::JoinFlag) { o->systemThread->join(); - releaseSystem(t, o); } o->state = Thread::JoinedState; } @@ -257,15 +249,17 @@ killZombies(Thread* t, Thread* o) killZombies(t, child); } - switch (o->state) { - case Thread::ZombieState: - join(t, o); - // fall through - - case Thread::JoinedState: - dispose(t, o, true); - - default: break; + if ((o->flags & Thread::SystemFlag) == 0) { + switch (o->state) { + case Thread::ZombieState: + join(t, o); + // fall through + + case Thread::JoinedState: + dispose(t, o, true); + + default: break; + } } } @@ -2623,23 +2617,7 @@ Thread::exit() } else { threadPeer(this, javaThread) = 0; - System::Monitor* myLock = lock; - System::Thread* mySystemThread = systemThread; - - { ACQUIRE_RAW(this, m->stateLock); - - while (flags & SystemFlag) { - m->stateLock->wait(systemThread, 0); - } - - atomicOr(&flags, Thread::DisposeFlag); - - enter(this, Thread::ZombieState); - } - - myLock->dispose(); - - mySystemThread->dispose(); + enter(this, Thread::ZombieState); } } } @@ -2647,14 +2625,12 @@ Thread::exit() void Thread::dispose() { - if ((flags & Thread::DisposeFlag) == 0) { - if (lock) { - lock->dispose(); - } - - if (systemThread) { - systemThread->dispose(); - } + if (lock) { + lock->dispose(); + } + + if (systemThread) { + systemThread->dispose(); } -- m->threadCount; diff --git a/src/machine.h b/src/machine.h index 0841eb4443..12aca3bc45 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1392,7 +1392,7 @@ class Thread { static const unsigned StressFlag = 1 << 4; static const unsigned ActiveFlag = 1 << 5; static const unsigned SystemFlag = 1 << 6; - static const unsigned DisposeFlag = 1 << 7; + static const unsigned JoinFlag = 1 << 7; class Protector { public: @@ -1988,6 +1988,7 @@ runThread(Thread* t, uintptr_t*) inline bool startThread(Thread* t, Thread* p) { + p->flags |= Thread::JoinFlag; return t->m->system->success(t->m->system->start(&(p->runnable))); } @@ -2784,19 +2785,12 @@ parameterFootprint(Thread* t, const char* s, bool static_); void addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object)); -inline bool -zombified(Thread* t) -{ - return t->state == Thread::ZombieState - or t->state == Thread::JoinedState; -} - inline bool acquireSystem(Thread* t, Thread* target) { ACQUIRE_RAW(t, t->m->stateLock); - if (not zombified(target)) { + if (t->state != Thread::JoinedState) { atomicOr(&(target->flags), Thread::SystemFlag); return true; } else { @@ -2809,7 +2803,7 @@ releaseSystem(Thread* t, Thread* target) { ACQUIRE_RAW(t, t->m->stateLock); - assert(t, not zombified(target)); + assert(t, t->state != Thread::JoinedState); atomicAnd(&(target->flags), ~Thread::SystemFlag); }