1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "CrossProcessMutex.h"
8 #include "mozilla/Unused.h"
10 #include "nsISupportsImpl.h"
15 pthread_mutex_t mMutex
;
16 mozilla::Atomic
<int32_t> mCount
;
23 static void InitMutex(pthread_mutex_t
* mMutex
) {
24 pthread_mutexattr_t mutexAttributes
;
25 pthread_mutexattr_init(&mutexAttributes
);
26 // Make the mutex reentrant so it behaves the same as a win32 mutex
27 if (pthread_mutexattr_settype(&mutexAttributes
, PTHREAD_MUTEX_RECURSIVE
)) {
30 if (pthread_mutexattr_setpshared(&mutexAttributes
, PTHREAD_PROCESS_SHARED
)) {
34 if (pthread_mutex_init(mMutex
, &mutexAttributes
)) {
39 CrossProcessMutex::CrossProcessMutex(const char*)
40 : mMutex(nullptr), mCount(nullptr) {
41 #if defined(MOZ_SANDBOX)
42 // POSIX mutexes in shared memory aren't guaranteed to be safe - and
43 // they specifically are not on Linux.
44 MOZ_RELEASE_ASSERT(false);
46 mSharedBuffer
= new ipc::SharedMemory
;
47 if (!mSharedBuffer
->Create(sizeof(MutexData
))) {
51 if (!mSharedBuffer
->Map(sizeof(MutexData
))) {
55 MutexData
* data
= static_cast<MutexData
*>(mSharedBuffer
->Memory());
61 mMutex
= &(data
->mMutex
);
62 mCount
= &(data
->mCount
);
67 MOZ_COUNT_CTOR(CrossProcessMutex
);
70 CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle
)
71 : mMutex(nullptr), mCount(nullptr) {
72 mSharedBuffer
= new ipc::SharedMemory
;
74 if (!mSharedBuffer
->IsHandleValid(aHandle
)) {
78 if (!mSharedBuffer
->SetHandle(std::move(aHandle
),
79 ipc::SharedMemory::RightsReadWrite
)) {
83 if (!mSharedBuffer
->Map(sizeof(MutexData
))) {
87 MutexData
* data
= static_cast<MutexData
*>(mSharedBuffer
->Memory());
93 mMutex
= &(data
->mMutex
);
94 mCount
= &(data
->mCount
);
95 int32_t count
= (*mCount
)++;
98 // The other side has already let go of their CrossProcessMutex, so now
99 // mMutex is garbage. We need to re-initialize it.
103 MOZ_COUNT_CTOR(CrossProcessMutex
);
106 CrossProcessMutex::~CrossProcessMutex() {
107 int32_t count
= --(*mCount
);
110 // Nothing can be done if the destroy fails so ignore return code.
111 Unused
<< pthread_mutex_destroy(mMutex
);
114 MOZ_COUNT_DTOR(CrossProcessMutex
);
117 void CrossProcessMutex::Lock() {
118 MOZ_ASSERT(*mCount
> 0, "Attempting to lock mutex with zero ref count");
119 pthread_mutex_lock(mMutex
);
122 void CrossProcessMutex::Unlock() {
123 MOZ_ASSERT(*mCount
> 0, "Attempting to unlock mutex with zero ref count");
124 pthread_mutex_unlock(mMutex
);
127 CrossProcessMutexHandle
CrossProcessMutex::CloneHandle() {
128 CrossProcessMutexHandle result
= ipc::SharedMemory::NULLHandle();
131 result
= mSharedBuffer
->CloneHandle();
140 } // namespace mozilla