1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/glue/CrossProcessMutex_posix.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,131 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "CrossProcessMutex.h" 1.10 +#include "mozilla/unused.h" 1.11 +#include "nsDebug.h" 1.12 +#include "nsISupportsImpl.h" 1.13 + 1.14 +namespace { 1.15 + 1.16 +struct MutexData { 1.17 + pthread_mutex_t mMutex; 1.18 + mozilla::Atomic<int32_t> mCount; 1.19 +}; 1.20 + 1.21 +} 1.22 + 1.23 +namespace mozilla { 1.24 + 1.25 +CrossProcessMutex::CrossProcessMutex(const char*) 1.26 + : mSharedBuffer(nullptr) 1.27 + , mMutex(nullptr) 1.28 + , mCount(nullptr) 1.29 +{ 1.30 + mSharedBuffer = new ipc::SharedMemoryBasic; 1.31 + if (!mSharedBuffer->Create(sizeof(MutexData))) { 1.32 + MOZ_CRASH(); 1.33 + } 1.34 + 1.35 + if (!mSharedBuffer->Map(sizeof(MutexData))) { 1.36 + MOZ_CRASH(); 1.37 + } 1.38 + 1.39 + MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory()); 1.40 + 1.41 + if (!data) { 1.42 + MOZ_CRASH(); 1.43 + } 1.44 + 1.45 + mMutex = &(data->mMutex); 1.46 + mCount = &(data->mCount); 1.47 + 1.48 + *mCount = 1; 1.49 + 1.50 + pthread_mutexattr_t mutexAttributes; 1.51 + pthread_mutexattr_init(&mutexAttributes); 1.52 + // Make the mutex reentrant so it behaves the same as a win32 mutex 1.53 + if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) { 1.54 + MOZ_CRASH(); 1.55 + } 1.56 + if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) { 1.57 + MOZ_CRASH(); 1.58 + } 1.59 + 1.60 + if (pthread_mutex_init(mMutex, &mutexAttributes)) { 1.61 + MOZ_CRASH(); 1.62 + } 1.63 + 1.64 + MOZ_COUNT_CTOR(CrossProcessMutex); 1.65 +} 1.66 + 1.67 +CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle) 1.68 + : mSharedBuffer(nullptr) 1.69 + , mMutex(nullptr) 1.70 + , mCount(nullptr) 1.71 +{ 1.72 + if (!ipc::SharedMemoryBasic::IsHandleValid(aHandle)) { 1.73 + MOZ_CRASH(); 1.74 + } 1.75 + 1.76 + mSharedBuffer = new ipc::SharedMemoryBasic(aHandle); 1.77 + 1.78 + if (!mSharedBuffer->Map(sizeof(MutexData))) { 1.79 + MOZ_CRASH(); 1.80 + } 1.81 + 1.82 + MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory()); 1.83 + 1.84 + if (!data) { 1.85 + MOZ_CRASH(); 1.86 + } 1.87 + 1.88 + mMutex = &(data->mMutex); 1.89 + mCount = &(data->mCount); 1.90 + (*mCount)++; 1.91 + 1.92 + MOZ_COUNT_CTOR(CrossProcessMutex); 1.93 +} 1.94 + 1.95 +CrossProcessMutex::~CrossProcessMutex() 1.96 +{ 1.97 + int32_t count = --(*mCount); 1.98 + 1.99 + if (count == 0) { 1.100 + // Nothing can be done if the destroy fails so ignore return code. 1.101 + unused << pthread_mutex_destroy(mMutex); 1.102 + } 1.103 + 1.104 + delete mSharedBuffer; 1.105 + MOZ_COUNT_DTOR(CrossProcessMutex); 1.106 +} 1.107 + 1.108 +void 1.109 +CrossProcessMutex::Lock() 1.110 +{ 1.111 + MOZ_ASSERT(*mCount > 0, "Attempting to lock mutex with zero ref count"); 1.112 + pthread_mutex_lock(mMutex); 1.113 +} 1.114 + 1.115 +void 1.116 +CrossProcessMutex::Unlock() 1.117 +{ 1.118 + MOZ_ASSERT(*mCount > 0, "Attempting to unlock mutex with zero ref count"); 1.119 + pthread_mutex_unlock(mMutex); 1.120 +} 1.121 + 1.122 +CrossProcessMutexHandle 1.123 +CrossProcessMutex::ShareToProcess(base::ProcessHandle aHandle) 1.124 +{ 1.125 + CrossProcessMutexHandle result = ipc::SharedMemoryBasic::NULLHandle(); 1.126 + 1.127 + if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aHandle, &result)) { 1.128 + MOZ_CRASH(); 1.129 + } 1.130 + 1.131 + return result; 1.132 +} 1.133 + 1.134 +}