LCOV - code coverage report
Current view: top level - ipc/glue - CrossProcessMutex_posix.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 41 63 65.1 %
Date: 2017-07-14 16:53:18 Functions: 5 7 71.4 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       7             : #include "CrossProcessMutex.h"
       8             : #include "mozilla/Unused.h"
       9             : #include "nsDebug.h"
      10             : #include "nsISupportsImpl.h"
      11             : 
      12             : namespace {
      13             : 
      14             : struct MutexData {
      15             :   pthread_mutex_t mMutex;
      16             :   mozilla::Atomic<int32_t> mCount;
      17             : };
      18             : 
      19             : } // namespace
      20             : 
      21             : namespace mozilla {
      22             : 
      23             : static void
      24           1 : InitMutex(pthread_mutex_t* mMutex)
      25             : {
      26             :   pthread_mutexattr_t mutexAttributes;
      27           1 :   pthread_mutexattr_init(&mutexAttributes);
      28             :   // Make the mutex reentrant so it behaves the same as a win32 mutex
      29           1 :   if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) {
      30           0 :     MOZ_CRASH();
      31             :   }
      32           1 :   if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) {
      33           0 :     MOZ_CRASH();
      34             :   }
      35             : 
      36           1 :   if (pthread_mutex_init(mMutex, &mutexAttributes)) {
      37           0 :     MOZ_CRASH();
      38             :   }
      39           1 : }
      40             : 
      41           1 : CrossProcessMutex::CrossProcessMutex(const char*)
      42             :     : mMutex(nullptr)
      43           1 :     , mCount(nullptr)
      44             : {
      45           1 :   mSharedBuffer = new ipc::SharedMemoryBasic;
      46           1 :   if (!mSharedBuffer->Create(sizeof(MutexData))) {
      47           0 :     MOZ_CRASH();
      48             :   }
      49             : 
      50           1 :   if (!mSharedBuffer->Map(sizeof(MutexData))) {
      51           0 :     MOZ_CRASH();
      52             :   }
      53             : 
      54           1 :   MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
      55             : 
      56           1 :   if (!data) {
      57           0 :     MOZ_CRASH();
      58             :   }
      59             : 
      60           1 :   mMutex = &(data->mMutex);
      61           1 :   mCount = &(data->mCount);
      62             : 
      63           1 :   *mCount = 1;
      64           1 :   InitMutex(mMutex);
      65             : 
      66           1 :   MOZ_COUNT_CTOR(CrossProcessMutex);
      67           1 : }
      68             : 
      69           2 : CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle)
      70             :     : mMutex(nullptr)
      71           2 :     , mCount(nullptr)
      72             : {
      73           2 :   mSharedBuffer = new ipc::SharedMemoryBasic;
      74             : 
      75           2 :   if (!mSharedBuffer->IsHandleValid(aHandle)) {
      76           0 :     MOZ_CRASH();
      77             :   }
      78             : 
      79           2 :   if (!mSharedBuffer->SetHandle(aHandle, ipc::SharedMemory::RightsReadWrite)) {
      80           0 :     MOZ_CRASH();
      81             :   }
      82             : 
      83           2 :   if (!mSharedBuffer->Map(sizeof(MutexData))) {
      84           0 :     MOZ_CRASH();
      85             :   }
      86             : 
      87           2 :   MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
      88             : 
      89           2 :   if (!data) {
      90           0 :     MOZ_CRASH();
      91             :   }
      92             : 
      93           2 :   mMutex = &(data->mMutex);
      94           2 :   mCount = &(data->mCount);
      95           2 :   int32_t count = (*mCount)++;
      96             : 
      97           2 :   if (count == 0) {
      98             :     // The other side has already let go of their CrossProcessMutex, so now
      99             :     // mMutex is garbage. We need to re-initialize it.
     100           0 :     InitMutex(mMutex);
     101             :   }
     102             : 
     103           2 :   MOZ_COUNT_CTOR(CrossProcessMutex);
     104           2 : }
     105             : 
     106           0 : CrossProcessMutex::~CrossProcessMutex()
     107             : {
     108           0 :   int32_t count = --(*mCount);
     109             : 
     110           0 :   if (count == 0) {
     111             :     // Nothing can be done if the destroy fails so ignore return code.
     112           0 :     Unused << pthread_mutex_destroy(mMutex);
     113             :   }
     114             : 
     115           0 :   MOZ_COUNT_DTOR(CrossProcessMutex);
     116           0 : }
     117             : 
     118             : void
     119           3 : CrossProcessMutex::Lock()
     120             : {
     121           3 :   MOZ_ASSERT(*mCount > 0, "Attempting to lock mutex with zero ref count");
     122           3 :   pthread_mutex_lock(mMutex);
     123           3 : }
     124             : 
     125             : void
     126           0 : CrossProcessMutex::Unlock()
     127             : {
     128           0 :   MOZ_ASSERT(*mCount > 0, "Attempting to unlock mutex with zero ref count");
     129           0 :   pthread_mutex_unlock(mMutex);
     130           0 : }
     131             : 
     132             : CrossProcessMutexHandle
     133           2 : CrossProcessMutex::ShareToProcess(base::ProcessId aTargetPid)
     134             : {
     135           2 :   CrossProcessMutexHandle result = ipc::SharedMemoryBasic::NULLHandle();
     136             : 
     137           2 :   if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aTargetPid, &result)) {
     138           0 :     MOZ_CRASH();
     139             :   }
     140             : 
     141           2 :   return result;
     142             : }
     143             : 
     144             : } // namespace mozilla

Generated by: LCOV version 1.13