< prev index next >
src/share/vm/runtime/thread.cpp
Print this page
*** 1324,1333 ****
--- 1324,1342 ----
{
MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag);
_watcher_thread = NULL;
Terminator_lock->notify();
}
+
+ // Deletion is done synchronously by the thread terminating the VM
+ // so that the WatcherThread deletion doesn't race with that thread as it
+ // tears down VM resources. That means 'this' may already have been
+ // deallocated so we can't reference it. However we must do some cleanup
+ // ourselves before allowing the native thread to terminate
+
+ ThreadLocalStorage::set_thread(NULL);
+
}
void WatcherThread::start() {
assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
*** 1342,1358 ****
assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
_startable = true;
}
void WatcherThread::stop() {
{
// Follow normal safepoint aware lock enter protocol since the
// WatcherThread is stopped by another JavaThread.
MutexLocker ml(PeriodicTask_lock);
_should_terminate = true;
! WatcherThread* watcher = watcher_thread();
if (watcher != NULL) {
// unpark the WatcherThread so it can see that it should terminate
watcher->unpark();
}
}
--- 1351,1368 ----
assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
_startable = true;
}
void WatcherThread::stop() {
+ WatcherThread* watcher = NULL;
{
// Follow normal safepoint aware lock enter protocol since the
// WatcherThread is stopped by another JavaThread.
MutexLocker ml(PeriodicTask_lock);
_should_terminate = true;
! watcher = watcher_thread();
if (watcher != NULL) {
// unpark the WatcherThread so it can see that it should terminate
watcher->unpark();
}
}
*** 1371,1380 ****
--- 1381,1394 ----
// suspend-equivalent condition solves that timeout problem.
//
Terminator_lock->wait(!Mutex::_no_safepoint_check_flag, 0,
Mutex::_as_suspend_equivalent_flag);
}
+
+ // can't get here till the WatcherThread has indicated it is terminating
+ if (watcher != NULL)
+ delete watcher;
}
void WatcherThread::unpark() {
assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
PeriodicTask_lock->notify();
< prev index next >