Bumping manifests a=b2g-bump
[gecko.git] / ipc / glue / CrossProcessMutex_posix.cpp
blob6b947f67c5c73c9060b956aa99c6341c0befdbf8
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "CrossProcessMutex.h"
7 #include "mozilla/unused.h"
8 #include "nsDebug.h"
9 #include "nsISupportsImpl.h"
11 namespace {
13 struct MutexData {
14 pthread_mutex_t mMutex;
15 mozilla::Atomic<int32_t> mCount;
20 namespace mozilla {
22 static void
23 InitMutex(pthread_mutex_t* mMutex)
25 pthread_mutexattr_t mutexAttributes;
26 pthread_mutexattr_init(&mutexAttributes);
27 // Make the mutex reentrant so it behaves the same as a win32 mutex
28 if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) {
29 MOZ_CRASH();
31 if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) {
32 MOZ_CRASH();
35 if (pthread_mutex_init(mMutex, &mutexAttributes)) {
36 MOZ_CRASH();
40 CrossProcessMutex::CrossProcessMutex(const char*)
41 : mMutex(nullptr)
42 , mCount(nullptr)
44 mSharedBuffer = new ipc::SharedMemoryBasic;
45 if (!mSharedBuffer->Create(sizeof(MutexData))) {
46 MOZ_CRASH();
49 if (!mSharedBuffer->Map(sizeof(MutexData))) {
50 MOZ_CRASH();
53 MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
55 if (!data) {
56 MOZ_CRASH();
59 mMutex = &(data->mMutex);
60 mCount = &(data->mCount);
62 *mCount = 1;
63 InitMutex(mMutex);
65 MOZ_COUNT_CTOR(CrossProcessMutex);
68 CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle)
69 : mMutex(nullptr)
70 , mCount(nullptr)
72 if (!ipc::SharedMemoryBasic::IsHandleValid(aHandle)) {
73 MOZ_CRASH();
76 mSharedBuffer = new ipc::SharedMemoryBasic(aHandle);
78 if (!mSharedBuffer->Map(sizeof(MutexData))) {
79 MOZ_CRASH();
82 MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
84 if (!data) {
85 MOZ_CRASH();
88 mMutex = &(data->mMutex);
89 mCount = &(data->mCount);
90 int32_t count = (*mCount)++;
92 if (count == 0) {
93 // The other side has already let go of their CrossProcessMutex, so now
94 // mMutex is garbage. We need to re-initialize it.
95 InitMutex(mMutex);
98 MOZ_COUNT_CTOR(CrossProcessMutex);
101 CrossProcessMutex::~CrossProcessMutex()
103 int32_t count = --(*mCount);
105 if (count == 0) {
106 // Nothing can be done if the destroy fails so ignore return code.
107 unused << pthread_mutex_destroy(mMutex);
110 MOZ_COUNT_DTOR(CrossProcessMutex);
113 void
114 CrossProcessMutex::Lock()
116 MOZ_ASSERT(*mCount > 0, "Attempting to lock mutex with zero ref count");
117 pthread_mutex_lock(mMutex);
120 void
121 CrossProcessMutex::Unlock()
123 MOZ_ASSERT(*mCount > 0, "Attempting to unlock mutex with zero ref count");
124 pthread_mutex_unlock(mMutex);
127 CrossProcessMutexHandle
128 CrossProcessMutex::ShareToProcess(base::ProcessHandle aHandle)
130 CrossProcessMutexHandle result = ipc::SharedMemoryBasic::NULLHandle();
132 if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aHandle, &result)) {
133 MOZ_CRASH();
136 return result;