< prev index next >

src/share/vm/runtime/thread.cpp

Print this page

        

@@ -1324,10 +1324,19 @@
   {
     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,17 +1351,18 @@
   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;
 
-    WatcherThread* watcher = watcher_thread();
+    watcher = watcher_thread();
     if (watcher != NULL) {
       // unpark the WatcherThread so it can see that it should terminate
       watcher->unpark();
     }
   }

@@ -1371,10 +1381,14 @@
     // 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 >