Bug 1503055 - Avoid deadlocking when rewinding to avoid a different deadlock, r=mccr8.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 29 Oct 2018 13:23:33 -1000
changeset 443518 62a1d3756cc209ae438e593479edd32c03eb525e
parent 443517 c5c10f26e38c40810997b409829e0cdbb84cfcd3
child 443603 d751dd2cd3370f63087f7fa36d836b86a83506b7
push id109411
push userbhackett@mozilla.com
push dateTue, 30 Oct 2018 21:45:13 +0000
treeherdermozilla-inbound@62a1d3756cc2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1503055
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1503055 - Avoid deadlocking when rewinding to avoid a different deadlock, r=mccr8.
toolkit/recordreplay/Lock.cpp
--- a/toolkit/recordreplay/Lock.cpp
+++ b/toolkit/recordreplay/Lock.cpp
@@ -124,17 +124,18 @@ Lock::Destroy(void* aNativeLock)
   delete lock;
 }
 
 /* static */ Lock*
 Lock::Find(void* aNativeLock)
 {
   MOZ_RELEASE_ASSERT(IsRecordingOrReplaying());
 
-  AutoReadSpinLock ex(gLocksLock);
+  Maybe<AutoReadSpinLock> ex;
+  ex.emplace(gLocksLock);
 
   if (gLocks) {
     LockMap::iterator iter = gLocks->find(aNativeLock);
     if (iter != gLocks->end()) {
       // Now that we know the lock is recorded, check whether thread events
       // should be generated right now. Doing things in this order avoids
       // reentrancy issues when initializing the thread-local state used by
       // these calls.
@@ -142,16 +143,17 @@ Lock::Find(void* aNativeLock)
       if (AreThreadEventsPassedThrough()) {
         return nullptr;
       }
       if (HasDivergedFromRecording()) {
         // When diverged from the recording, don't allow uses of locks that are
         // held by idling threads that have not diverged from the recording.
         // This will cause the process to deadlock, so rewind instead.
         if (lock->mOwner && Thread::GetById(lock->mOwner)->IsIdle()) {
+          ex.reset();
           EnsureNotDivergedFromRecording();
           Unreachable();
         }
         return nullptr;
       }
       return lock;
     }
   }