Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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;
16 };
18 }
20 namespace mozilla {
22 CrossProcessMutex::CrossProcessMutex(const char*)
23 : mSharedBuffer(nullptr)
24 , mMutex(nullptr)
25 , mCount(nullptr)
26 {
27 mSharedBuffer = new ipc::SharedMemoryBasic;
28 if (!mSharedBuffer->Create(sizeof(MutexData))) {
29 MOZ_CRASH();
30 }
32 if (!mSharedBuffer->Map(sizeof(MutexData))) {
33 MOZ_CRASH();
34 }
36 MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
38 if (!data) {
39 MOZ_CRASH();
40 }
42 mMutex = &(data->mMutex);
43 mCount = &(data->mCount);
45 *mCount = 1;
47 pthread_mutexattr_t mutexAttributes;
48 pthread_mutexattr_init(&mutexAttributes);
49 // Make the mutex reentrant so it behaves the same as a win32 mutex
50 if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) {
51 MOZ_CRASH();
52 }
53 if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) {
54 MOZ_CRASH();
55 }
57 if (pthread_mutex_init(mMutex, &mutexAttributes)) {
58 MOZ_CRASH();
59 }
61 MOZ_COUNT_CTOR(CrossProcessMutex);
62 }
64 CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle)
65 : mSharedBuffer(nullptr)
66 , mMutex(nullptr)
67 , mCount(nullptr)
68 {
69 if (!ipc::SharedMemoryBasic::IsHandleValid(aHandle)) {
70 MOZ_CRASH();
71 }
73 mSharedBuffer = new ipc::SharedMemoryBasic(aHandle);
75 if (!mSharedBuffer->Map(sizeof(MutexData))) {
76 MOZ_CRASH();
77 }
79 MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
81 if (!data) {
82 MOZ_CRASH();
83 }
85 mMutex = &(data->mMutex);
86 mCount = &(data->mCount);
87 (*mCount)++;
89 MOZ_COUNT_CTOR(CrossProcessMutex);
90 }
92 CrossProcessMutex::~CrossProcessMutex()
93 {
94 int32_t count = --(*mCount);
96 if (count == 0) {
97 // Nothing can be done if the destroy fails so ignore return code.
98 unused << pthread_mutex_destroy(mMutex);
99 }
101 delete mSharedBuffer;
102 MOZ_COUNT_DTOR(CrossProcessMutex);
103 }
105 void
106 CrossProcessMutex::Lock()
107 {
108 MOZ_ASSERT(*mCount > 0, "Attempting to lock mutex with zero ref count");
109 pthread_mutex_lock(mMutex);
110 }
112 void
113 CrossProcessMutex::Unlock()
114 {
115 MOZ_ASSERT(*mCount > 0, "Attempting to unlock mutex with zero ref count");
116 pthread_mutex_unlock(mMutex);
117 }
119 CrossProcessMutexHandle
120 CrossProcessMutex::ShareToProcess(base::ProcessHandle aHandle)
121 {
122 CrossProcessMutexHandle result = ipc::SharedMemoryBasic::NULLHandle();
124 if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aHandle, &result)) {
125 MOZ_CRASH();
126 }
128 return result;
129 }
131 }