Bug 1024728 - Gracefully handle a CrossProcessMutex being initialized with a stale handle. r=khuey, a=lmandel
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 20 Jun 2014 17:06:36 -0400
changeset 195554 04303003b89691a86dee436cc152340ba2bf1d14
parent 195553 b124230d0fa9a7d2f7ebdaef99f4921b4e141676
child 195555 f89e20f3ad3a2a7efa8c39039f6929f7991015c8
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-esr52@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey, lmandel
bugs1024728
milestone32.0a2
Bug 1024728 - Gracefully handle a CrossProcessMutex being initialized with a stale handle. r=khuey, a=lmandel
ipc/glue/CrossProcessMutex_posix.cpp
--- a/ipc/glue/CrossProcessMutex_posix.cpp
+++ b/ipc/glue/CrossProcessMutex_posix.cpp
@@ -14,16 +14,34 @@ struct MutexData {
   pthread_mutex_t mMutex;
   mozilla::Atomic<int32_t> mCount;
 };
 
 }
 
 namespace mozilla {
 
+static void
+InitMutex(pthread_mutex_t* mMutex)
+{
+  pthread_mutexattr_t mutexAttributes;
+  pthread_mutexattr_init(&mutexAttributes);
+  // Make the mutex reentrant so it behaves the same as a win32 mutex
+  if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) {
+    MOZ_CRASH();
+  }
+  if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) {
+    MOZ_CRASH();
+  }
+
+  if (pthread_mutex_init(mMutex, &mutexAttributes)) {
+    MOZ_CRASH();
+  }
+}
+
 CrossProcessMutex::CrossProcessMutex(const char*)
     : mSharedBuffer(nullptr)
     , mMutex(nullptr)
     , mCount(nullptr)
 {
   mSharedBuffer = new ipc::SharedMemoryBasic;
   if (!mSharedBuffer->Create(sizeof(MutexData))) {
     MOZ_CRASH();
@@ -38,30 +56,17 @@ CrossProcessMutex::CrossProcessMutex(con
   if (!data) {
     MOZ_CRASH();
   }
 
   mMutex = &(data->mMutex);
   mCount = &(data->mCount);
 
   *mCount = 1;
-
-  pthread_mutexattr_t mutexAttributes;
-  pthread_mutexattr_init(&mutexAttributes);
-  // Make the mutex reentrant so it behaves the same as a win32 mutex
-  if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) {
-    MOZ_CRASH();
-  }
-  if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) {
-    MOZ_CRASH();
-  }
-
-  if (pthread_mutex_init(mMutex, &mutexAttributes)) {
-    MOZ_CRASH();
-  }
+  InitMutex(mMutex);
 
   MOZ_COUNT_CTOR(CrossProcessMutex);
 }
 
 CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle)
     : mSharedBuffer(nullptr)
     , mMutex(nullptr)
     , mCount(nullptr)
@@ -79,17 +84,23 @@ CrossProcessMutex::CrossProcessMutex(Cro
   MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
 
   if (!data) {
     MOZ_CRASH();
   }
 
   mMutex = &(data->mMutex);
   mCount = &(data->mCount);
-  (*mCount)++;
+  int32_t count = (*mCount)++;
+
+  if (count == 0) {
+    // The other side has already let go of their CrossProcessMutex, so now
+    // mMutex is garbage. We need to re-initialize it.
+    InitMutex(mMutex);
+  }
 
   MOZ_COUNT_CTOR(CrossProcessMutex);
 }
 
 CrossProcessMutex::~CrossProcessMutex()
 {
   int32_t count = --(*mCount);