ipc/glue/CrossProcessMutex_posix.cpp

branch
TOR_BUG_9701
changeset 14
925c144e1f1f
equal deleted inserted replaced
-1:000000000000 0:320dc750304f
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/. */
5
6 #include "CrossProcessMutex.h"
7 #include "mozilla/unused.h"
8 #include "nsDebug.h"
9 #include "nsISupportsImpl.h"
10
11 namespace {
12
13 struct MutexData {
14 pthread_mutex_t mMutex;
15 mozilla::Atomic<int32_t> mCount;
16 };
17
18 }
19
20 namespace mozilla {
21
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 }
31
32 if (!mSharedBuffer->Map(sizeof(MutexData))) {
33 MOZ_CRASH();
34 }
35
36 MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
37
38 if (!data) {
39 MOZ_CRASH();
40 }
41
42 mMutex = &(data->mMutex);
43 mCount = &(data->mCount);
44
45 *mCount = 1;
46
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 }
56
57 if (pthread_mutex_init(mMutex, &mutexAttributes)) {
58 MOZ_CRASH();
59 }
60
61 MOZ_COUNT_CTOR(CrossProcessMutex);
62 }
63
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 }
72
73 mSharedBuffer = new ipc::SharedMemoryBasic(aHandle);
74
75 if (!mSharedBuffer->Map(sizeof(MutexData))) {
76 MOZ_CRASH();
77 }
78
79 MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
80
81 if (!data) {
82 MOZ_CRASH();
83 }
84
85 mMutex = &(data->mMutex);
86 mCount = &(data->mCount);
87 (*mCount)++;
88
89 MOZ_COUNT_CTOR(CrossProcessMutex);
90 }
91
92 CrossProcessMutex::~CrossProcessMutex()
93 {
94 int32_t count = --(*mCount);
95
96 if (count == 0) {
97 // Nothing can be done if the destroy fails so ignore return code.
98 unused << pthread_mutex_destroy(mMutex);
99 }
100
101 delete mSharedBuffer;
102 MOZ_COUNT_DTOR(CrossProcessMutex);
103 }
104
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 }
111
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 }
118
119 CrossProcessMutexHandle
120 CrossProcessMutex::ShareToProcess(base::ProcessHandle aHandle)
121 {
122 CrossProcessMutexHandle result = ipc::SharedMemoryBasic::NULLHandle();
123
124 if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aHandle, &result)) {
125 MOZ_CRASH();
126 }
127
128 return result;
129 }
130
131 }

mercurial