mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8218483: Crash in "assert(_daemon_threads_count->get_value() > daemon_count) failed: thread count mismatch 5 : 5"
Reviewed-by: dcubed, stuefe
This commit is contained in:
parent
18146afe7f
commit
2f20909d10
4 changed files with 16 additions and 15 deletions
|
@ -4166,7 +4166,7 @@ static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool dae
|
||||||
|
|
||||||
if (attach_failed) {
|
if (attach_failed) {
|
||||||
// Added missing cleanup
|
// Added missing cleanup
|
||||||
thread->cleanup_failed_attach_current_thread();
|
thread->cleanup_failed_attach_current_thread(daemon);
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2021,6 +2021,10 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||||
_timer_exit_phase1.stop();
|
_timer_exit_phase1.stop();
|
||||||
_timer_exit_phase2.start();
|
_timer_exit_phase2.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Capture daemon status before the thread is marked as terminated.
|
||||||
|
bool daemon = is_daemon(threadObj());
|
||||||
|
|
||||||
// Notify waiters on thread object. This has to be done after exit() is called
|
// Notify waiters on thread object. This has to be done after exit() is called
|
||||||
// on the thread (if the thread is the last thread in a daemon ThreadGroup the
|
// on the thread (if the thread is the last thread in a daemon ThreadGroup the
|
||||||
// group should have the destroyed bit set before waiters are notified).
|
// group should have the destroyed bit set before waiters are notified).
|
||||||
|
@ -2089,7 +2093,7 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||||
_timer_exit_phase4.start();
|
_timer_exit_phase4.start();
|
||||||
}
|
}
|
||||||
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
|
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
|
||||||
Threads::remove(this);
|
Threads::remove(this, daemon);
|
||||||
|
|
||||||
if (log_is_enabled(Debug, os, thread, timer)) {
|
if (log_is_enabled(Debug, os, thread, timer)) {
|
||||||
_timer_exit_phase4.stop();
|
_timer_exit_phase4.stop();
|
||||||
|
@ -2107,7 +2111,7 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JavaThread::cleanup_failed_attach_current_thread() {
|
void JavaThread::cleanup_failed_attach_current_thread(bool is_daemon) {
|
||||||
if (active_handles() != NULL) {
|
if (active_handles() != NULL) {
|
||||||
JNIHandleBlock* block = active_handles();
|
JNIHandleBlock* block = active_handles();
|
||||||
set_active_handles(NULL);
|
set_active_handles(NULL);
|
||||||
|
@ -2129,7 +2133,7 @@ void JavaThread::cleanup_failed_attach_current_thread() {
|
||||||
|
|
||||||
BarrierSet::barrier_set()->on_thread_detach(this);
|
BarrierSet::barrier_set()->on_thread_detach(this);
|
||||||
|
|
||||||
Threads::remove(this);
|
Threads::remove(this, is_daemon);
|
||||||
this->smr_delete();
|
this->smr_delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4455,7 +4459,7 @@ void Threads::add(JavaThread* p, bool force_daemon) {
|
||||||
Events::log(p, "Thread added: " INTPTR_FORMAT, p2i(p));
|
Events::log(p, "Thread added: " INTPTR_FORMAT, p2i(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Threads::remove(JavaThread* p) {
|
void Threads::remove(JavaThread* p, bool is_daemon) {
|
||||||
|
|
||||||
// Reclaim the ObjectMonitors from the omInUseList and omFreeList of the moribund thread.
|
// Reclaim the ObjectMonitors from the omInUseList and omFreeList of the moribund thread.
|
||||||
ObjectSynchronizer::omFlush(p);
|
ObjectSynchronizer::omFlush(p);
|
||||||
|
@ -4484,11 +4488,8 @@ void Threads::remove(JavaThread* p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_number_of_threads--;
|
_number_of_threads--;
|
||||||
oop threadObj = p->threadObj();
|
if (!is_daemon) {
|
||||||
bool daemon = true;
|
|
||||||
if (!is_daemon(threadObj)) {
|
|
||||||
_number_of_non_daemon_threads--;
|
_number_of_non_daemon_threads--;
|
||||||
daemon = false;
|
|
||||||
|
|
||||||
// Only one thread left, do a notify on the Threads_lock so a thread waiting
|
// Only one thread left, do a notify on the Threads_lock so a thread waiting
|
||||||
// on destroy_vm will wake up.
|
// on destroy_vm will wake up.
|
||||||
|
@ -4496,7 +4497,7 @@ void Threads::remove(JavaThread* p) {
|
||||||
Threads_lock->notify_all();
|
Threads_lock->notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ThreadService::remove_thread(p, daemon);
|
ThreadService::remove_thread(p, is_daemon);
|
||||||
|
|
||||||
// Make sure that safepoint code disregard this thread. This is needed since
|
// Make sure that safepoint code disregard this thread. This is needed since
|
||||||
// the thread might mess around with locks after this point. This can cause it
|
// the thread might mess around with locks after this point. This can cause it
|
||||||
|
|
|
@ -1242,7 +1242,7 @@ class JavaThread: public Thread {
|
||||||
};
|
};
|
||||||
void exit(bool destroy_vm, ExitType exit_type = normal_exit);
|
void exit(bool destroy_vm, ExitType exit_type = normal_exit);
|
||||||
|
|
||||||
void cleanup_failed_attach_current_thread();
|
void cleanup_failed_attach_current_thread(bool is_daemon);
|
||||||
|
|
||||||
// Testers
|
// Testers
|
||||||
virtual bool is_Java_thread() const { return true; }
|
virtual bool is_Java_thread() const { return true; }
|
||||||
|
@ -2235,7 +2235,7 @@ class Threads: AllStatic {
|
||||||
// force_daemon is a concession to JNI, where we may need to add a
|
// force_daemon is a concession to JNI, where we may need to add a
|
||||||
// thread to the thread list before allocating its thread object
|
// thread to the thread list before allocating its thread object
|
||||||
static void add(JavaThread* p, bool force_daemon = false);
|
static void add(JavaThread* p, bool force_daemon = false);
|
||||||
static void remove(JavaThread* p);
|
static void remove(JavaThread* p, bool is_daemon);
|
||||||
static void non_java_threads_do(ThreadClosure* tc);
|
static void non_java_threads_do(ThreadClosure* tc);
|
||||||
static void java_threads_do(ThreadClosure* tc);
|
static void java_threads_do(ThreadClosure* tc);
|
||||||
static void java_threads_and_vm_thread_do(ThreadClosure* tc);
|
static void java_threads_and_vm_thread_do(ThreadClosure* tc);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -66,7 +66,7 @@ public:
|
||||||
// Override as JavaThread::post_run() calls JavaThread::exit which
|
// Override as JavaThread::post_run() calls JavaThread::exit which
|
||||||
// expects a valid thread object oop.
|
// expects a valid thread object oop.
|
||||||
virtual void post_run() {
|
virtual void post_run() {
|
||||||
Threads::remove(this);
|
Threads::remove(this, false);
|
||||||
this->smr_delete();
|
this->smr_delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ public:
|
||||||
// Override as JavaThread::post_run() calls JavaThread::exit which
|
// Override as JavaThread::post_run() calls JavaThread::exit which
|
||||||
// expects a valid thread object oop. And we need to call signal.
|
// expects a valid thread object oop. And we need to call signal.
|
||||||
void post_run() {
|
void post_run() {
|
||||||
Threads::remove(this);
|
Threads::remove(this, false);
|
||||||
_post->signal();
|
_post->signal();
|
||||||
this->smr_delete();
|
this->smr_delete();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue