diff src/os/linux/vm/os_linux.cpp @ 17845:21dd1c827123

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
author kevinw
date Wed, 02 Apr 2014 18:40:52 +0200
parents 56e7f5560e60
children 6048424d3865
line wrap: on
line diff
--- a/src/os/linux/vm/os_linux.cpp	Tue Apr 08 14:55:16 2014 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Wed Apr 02 18:40:52 2014 +0200
@@ -1074,9 +1074,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;
 }