8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
Reviewed-by: dholmes, dsamersoff
Contributed-by: andreas.eriksson@oracle.com
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Apr 02 16:08:59 2014 +0100
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Apr 02 18:40:52 2014 +0200
@@ -917,9 +917,20 @@
//////////////////////////////////////////////////////////////////////////////
// thread local storage
+// Restore the thread pointer if the destructor is called. This is in case
+// someone from JNI code sets up a destructor with pthread_key_create to run
+// detachCurrentThread on thread death. Unless we restore the thread pointer we
+// will hang or crash. When detachCurrentThread is called the key will be set
+// to null and we will not be called again. If detachCurrentThread is never
+// called we could loop forever depending on the pthread implementation.
+static void restore_thread_pointer(void* p) {
+ Thread* thread = (Thread*) p;
+ os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
+}
+
int os::allocate_thread_local_storage() {
pthread_key_t key;
- int rslt = pthread_key_create(&key, NULL);
+ int rslt = pthread_key_create(&key, restore_thread_pointer);
assert(rslt == 0, "cannot allocate thread local storage");
return (int)key;
}
--- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Apr 02 16:08:59 2014 +0100
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Apr 02 18:40:52 2014 +0200
@@ -1032,9 +1032,20 @@
//////////////////////////////////////////////////////////////////////////////
// thread local storage
+// Restore the thread pointer if the destructor is called. This is in case
+// someone from JNI code sets up a destructor with pthread_key_create to run
+// detachCurrentThread on thread death. Unless we restore the thread pointer we
+// will hang or crash. When detachCurrentThread is called the key will be set
+// to null and we will not be called again. If detachCurrentThread is never
+// called we could loop forever depending on the pthread implementation.
+static void restore_thread_pointer(void* p) {
+ Thread* thread = (Thread*) p;
+ os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
+}
+
int os::allocate_thread_local_storage() {
pthread_key_t key;
- int rslt = pthread_key_create(&key, NULL);
+ int rslt = pthread_key_create(&key, restore_thread_pointer);
assert(rslt == 0, "cannot allocate thread local storage");
return (int)key;
}
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Wed Apr 02 16:08:59 2014 +0100
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Wed Apr 02 18:40:52 2014 +0200
@@ -305,6 +305,9 @@
_terminate_lock->notify();
}
+ // Thread destructor usually does this.
+ ThreadLocalStorage::set_thread(NULL);
+
// Deletion must be done synchronously by the JNI DestroyJavaVM thread
// so that the VMThread deletion completes before the main thread frees
// up the CodeHeap.