diff options
| author | 2014-12-10 22:22:14 +0000 | |
|---|---|---|
| committer | 2014-12-10 22:22:15 +0000 | |
| commit | 2cd6142727f1d9e5b71e942ea4c56e3c3810f8d0 (patch) | |
| tree | 053c34eca63eea760c1a6dd2b71bc80aa1e647b5 | |
| parent | 2387a59bf0e5bcc8f3aad8195eb1eea63d00939b (diff) | |
| parent | cef50f0487929f72183623bc2a5819cf3a63bff6 (diff) | |
Merge "Stop daemon threads in runtime shutdown"
| -rw-r--r-- | runtime/base/mutex.cc | 8 | ||||
| -rw-r--r-- | runtime/runtime.cc | 17 | ||||
| -rw-r--r-- | runtime/well_known_classes.cc | 2 | ||||
| -rw-r--r-- | runtime/well_known_classes.h | 1 |
4 files changed, 26 insertions, 2 deletions
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc index aa2aefc318..da78082f85 100644 --- a/runtime/base/mutex.cc +++ b/runtime/base/mutex.cc @@ -327,8 +327,12 @@ Mutex::~Mutex() { LOG(shutting_down ? WARNING : FATAL) << "destroying mutex with owner: " << exclusive_owner_; } else { CHECK_EQ(exclusive_owner_, 0U) << "unexpectedly found an owner on unlocked mutex " << name_; - CHECK_EQ(num_contenders_.LoadSequentiallyConsistent(), 0) - << "unexpectedly found a contender on mutex " << name_; + if (level_ != kMonitorLock) { + // Only check the lock level for non monitor locks since we may still have java threads + // waiting on monitors. + CHECK_EQ(num_contenders_.LoadSequentiallyConsistent(), 0) + << "unexpectedly found a contender on mutex " << name_; + } } #else // We can't use CHECK_MUTEX_CALL here because on shutdown a suspended daemon thread diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 078e7d24e1..32d787aeca 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -190,6 +190,13 @@ Runtime::~Runtime() { } Thread* self = Thread::Current(); + if (self == nullptr) { + CHECK(AttachCurrentThread("Shutdown thread", false, nullptr, false)); + self = Thread::Current(); + } else { + LOG(WARNING) << "Current thread not detached in Runtime shutdown"; + } + { MutexLock mu(self, *Locks::runtime_shutdown_lock_); shutting_down_started_ = true; @@ -198,6 +205,16 @@ Runtime::~Runtime() { } shutting_down_ = true; } + // Shutdown and wait for the daemons. + CHECK(self != nullptr); + if (IsFinishedStarting()) { + self->ClearException(); + self->GetJniEnv()->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons, + WellKnownClasses::java_lang_Daemons_stop); + } + DetachCurrentThread(); + self = nullptr; + // Shut down background profiler before the runtime exits. if (profiler_started_) { BackgroundMethodSamplingProfiler::Shutdown(); diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 16338c476d..80bed23b77 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -69,6 +69,7 @@ jmethodID WellKnownClasses::java_lang_ClassNotFoundException_init; jmethodID WellKnownClasses::java_lang_Daemons_requestGC; jmethodID WellKnownClasses::java_lang_Daemons_requestHeapTrim; jmethodID WellKnownClasses::java_lang_Daemons_start; +jmethodID WellKnownClasses::java_lang_Daemons_stop; jmethodID WellKnownClasses::java_lang_Double_valueOf; jmethodID WellKnownClasses::java_lang_Float_valueOf; jmethodID WellKnownClasses::java_lang_Integer_valueOf; @@ -207,6 +208,7 @@ void WellKnownClasses::Init(JNIEnv* env) { java_lang_Daemons_requestGC = CacheMethod(env, java_lang_Daemons, true, "requestGC", "()V"); java_lang_Daemons_requestHeapTrim = CacheMethod(env, java_lang_Daemons, true, "requestHeapTrim", "()V"); java_lang_Daemons_start = CacheMethod(env, java_lang_Daemons, true, "start", "()V"); + java_lang_Daemons_stop = CacheMethod(env, java_lang_Daemons, true, "stop", "()V"); ScopedLocalRef<jclass> java_lang_ref_FinalizerReference(env, env->FindClass("java/lang/ref/FinalizerReference")); java_lang_ref_FinalizerReference_add = CacheMethod(env, java_lang_ref_FinalizerReference.get(), true, "add", "(Ljava/lang/Object;)V"); diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h index d651b90c07..cb75e6ed7d 100644 --- a/runtime/well_known_classes.h +++ b/runtime/well_known_classes.h @@ -80,6 +80,7 @@ struct WellKnownClasses { static jmethodID java_lang_Daemons_requestGC; static jmethodID java_lang_Daemons_requestHeapTrim; static jmethodID java_lang_Daemons_start; + static jmethodID java_lang_Daemons_stop; static jmethodID java_lang_Double_valueOf; static jmethodID java_lang_Float_valueOf; static jmethodID java_lang_Integer_valueOf; |