summaryrefslogtreecommitdiff
path: root/runtime/base/mutex-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/base/mutex-inl.h')
-rw-r--r--runtime/base/mutex-inl.h19
1 files changed, 11 insertions, 8 deletions
diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h
index bd8de877e0..08b370ec4e 100644
--- a/runtime/base/mutex-inl.h
+++ b/runtime/base/mutex-inl.h
@@ -21,9 +21,7 @@
#include "mutex.h"
-#include "base/stringprintf.h"
#include "base/value_object.h"
-#include "runtime.h"
#include "thread.h"
#include "utils.h"
@@ -59,8 +57,7 @@ static inline void CheckUnattachedThread(LockLevel level) NO_THREAD_SAFETY_ANALY
// on a thread. Lock checking is disabled to avoid deadlock when checking shutdown lock.
// TODO: tighten this check.
if (kDebugLocking) {
- Runtime* runtime = Runtime::Current();
- CHECK(runtime == nullptr || !runtime->IsStarted() || runtime->IsShuttingDownLocked() ||
+ CHECK(!Locks::IsSafeToCallAbortRacy() ||
// Used during thread creation to avoid races with runtime shutdown. Thread::Current not
// yet established.
level == kRuntimeShutdownLock ||
@@ -73,6 +70,11 @@ static inline void CheckUnattachedThread(LockLevel level) NO_THREAD_SAFETY_ANALY
level == kThreadListLock ||
// Ignore logging which may or may not have set up thread data structures.
level == kLoggingLock ||
+ // When transitioning from suspended to runnable, a daemon thread might be in
+ // a situation where the runtime is shutting down. To not crash our debug locking
+ // mechanism we just pass null Thread* to the MutexLock during that transition
+ // (see Thread::TransitionFromSuspendedToRunnable).
+ level == kThreadSuspendCountLock ||
// Avoid recursive death.
level == kAbortLock) << level;
}
@@ -87,13 +89,14 @@ inline void BaseMutex::RegisterAsLocked(Thread* self) {
// Check if a bad Mutex of this level or lower is held.
bool bad_mutexes_held = false;
for (int i = level_; i >= 0; --i) {
- BaseMutex* held_mutex = self->GetHeldMutex(static_cast<LockLevel>(i));
- if (UNLIKELY(held_mutex != nullptr)) {
+ LockLevel lock_level_i = static_cast<LockLevel>(i);
+ BaseMutex* held_mutex = self->GetHeldMutex(lock_level_i);
+ if (UNLIKELY(held_mutex != nullptr) && lock_level_i != kAbortLock) {
LOG(ERROR) << "Lock level violation: holding \"" << held_mutex->name_ << "\" "
- << "(level " << LockLevel(i) << " - " << i
+ << "(level " << lock_level_i << " - " << i
<< ") while locking \"" << name_ << "\" "
<< "(level " << level_ << " - " << static_cast<int>(level_) << ")";
- if (i > kAbortLock) {
+ if (lock_level_i > kAbortLock) {
// Only abort in the check below if this is more than abort level lock.
bad_mutexes_held = true;
}