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"
9 #include "nsISupportsImpl.h"
14 pthread_mutex_t mMutex
;
15 mozilla::Atomic
<int32_t> mCount
;
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
)) {
31 if (pthread_mutexattr_setpshared(&mutexAttributes
, PTHREAD_PROCESS_SHARED
)) {
35 if (pthread_mutex_init(mMutex
, &mutexAttributes
)) {
40 CrossProcessMutex::CrossProcessMutex(const char*)
44 mSharedBuffer
= new ipc::SharedMemoryBasic
;
45 if (!mSharedBuffer
->Create(sizeof(MutexData
))) {
49 if (!mSharedBuffer
->Map(sizeof(MutexData
))) {
53 MutexData
* data
= static_cast<MutexData
*>(mSharedBuffer
->memory());
59 mMutex
= &(data
->mMutex
);
60 mCount
= &(data
->mCount
);
65 MOZ_COUNT_CTOR(CrossProcessMutex
);
68 CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle
)
72 if (!ipc::SharedMemoryBasic::IsHandleValid(aHandle
)) {
76 mSharedBuffer
= new ipc::SharedMemoryBasic(aHandle
);
78 if (!mSharedBuffer
->Map(sizeof(MutexData
))) {
82 MutexData
* data
= static_cast<MutexData
*>(mSharedBuffer
->memory());
88 mMutex
= &(data
->mMutex
);
89 mCount
= &(data
->mCount
);
90 int32_t count
= (*mCount
)++;
93 // The other side has already let go of their CrossProcessMutex, so now
94 // mMutex is garbage. We need to re-initialize it.
98 MOZ_COUNT_CTOR(CrossProcessMutex
);
101 CrossProcessMutex::~CrossProcessMutex()
103 int32_t count
= --(*mCount
);
106 // Nothing can be done if the destroy fails so ignore return code.
107 unused
<< pthread_mutex_destroy(mMutex
);
110 MOZ_COUNT_DTOR(CrossProcessMutex
);
114 CrossProcessMutex::Lock()
116 MOZ_ASSERT(*mCount
> 0, "Attempting to lock mutex with zero ref count");
117 pthread_mutex_lock(mMutex
);
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
)) {