8154715: Missing destructor and/or TLS clearing calls for terminating threads

Clear TLS on return from thread->run() unless already done. Prohibit asynchronous thread deletion.

Reviewed-by: stefank, sspitsyn
This commit is contained in:
Brian Gardner 2016-05-11 01:02:28 -04:00 committed by David Holmes
parent cdc0b9792f
commit 0e8376bd17
9 changed files with 116 additions and 52 deletions

View file

@ -638,7 +638,7 @@ bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
// create new thread
// Thread start routine for all newly created threads
static void *java_start(Thread *thread) {
static void *thread_native_entry(Thread *thread) {
// Try to randomize the cache line index of hot stack frames.
// This helps when threads of the same stack traces evict each other's
// cache lines. The threads can be either from the same JVM instance, or
@ -690,6 +690,15 @@ static void *java_start(Thread *thread) {
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
// If a thread has not deleted itself ("delete this") as part of its
// termination sequence, we have to ensure thread-local-storage is
// cleared before we actually terminate. No threads should ever be
// deleted asynchronously with respect to their termination.
if (Thread::current_or_null_safe() != NULL) {
assert(Thread::current_or_null_safe() == thread, "current thread is wrong");
thread->clear_thread_current();
}
return 0;
}
@ -753,7 +762,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
{
pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
char buf[64];
if (ret == 0) {
@ -881,18 +890,21 @@ void os::pd_start_thread(Thread* thread) {
void os::free_thread(OSThread* osthread) {
assert(osthread != NULL, "osthread not set");
if (Thread::current()->osthread() == osthread) {
// We are told to free resources of the argument thread,
// but we can only really operate on the current thread.
assert(Thread::current()->osthread() == osthread,
"os::free_thread but not current thread");
#ifdef ASSERT
sigset_t current;
sigemptyset(&current);
pthread_sigmask(SIG_SETMASK, NULL, &current);
assert(!sigismember(&current, SR_signum), "SR signal should not be blocked!");
sigset_t current;
sigemptyset(&current);
pthread_sigmask(SIG_SETMASK, NULL, &current);
assert(!sigismember(&current, SR_signum), "SR signal should not be blocked!");
#endif
// Restore caller's signal mask
sigset_t sigmask = osthread->caller_sigmask();
pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
}
// Restore caller's signal mask
sigset_t sigmask = osthread->caller_sigmask();
pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
delete osthread;
}