# HG changeset patch # User kevinw # Date 1397040508 25200 # Node ID 58fab66a82971a4f54c59614d29e141b6fb4dd82 # Parent 8847586c9037e0e5eb193c9acff500e65beab94f# Parent 21dd1c8271230c81c4dc5f6e0145bb3195346e5c Merge diff -r 8847586c9037 -r 58fab66a8297 src/os/bsd/vm/os_bsd.cpp --- a/src/os/bsd/vm/os_bsd.cpp Thu Apr 03 17:49:31 2014 +0400 +++ b/src/os/bsd/vm/os_bsd.cpp Wed Apr 09 03:48:28 2014 -0700 @@ -914,9 +914,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; } diff -r 8847586c9037 -r 58fab66a8297 src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Thu Apr 03 17:49:31 2014 +0400 +++ b/src/os/linux/vm/os_linux.cpp Wed Apr 09 03:48:28 2014 -0700 @@ -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; } diff -r 8847586c9037 -r 58fab66a8297 src/share/vm/runtime/vmThread.cpp --- a/src/share/vm/runtime/vmThread.cpp Thu Apr 03 17:49:31 2014 +0400 +++ b/src/share/vm/runtime/vmThread.cpp Wed Apr 09 03:48:28 2014 -0700 @@ -316,6 +316,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.