Blame xpcom/threads/RecursiveMutex.cpp

Packit f0b94e
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#include "mozilla/RecursiveMutex.h"
Packit f0b94e
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
#include <windows.h>
Packit f0b94e
Packit f0b94e
#define NativeHandle(m) (reinterpret_cast<CRITICAL_SECTION*>(&m))
Packit f0b94e
#endif
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
Packit f0b94e
RecursiveMutex::RecursiveMutex(
Packit f0b94e
    const char* aName MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
Packit f0b94e
    : BlockingResourceBase(aName, eRecursiveMutex)
Packit f0b94e
#ifdef DEBUG
Packit f0b94e
      ,
Packit f0b94e
      mOwningThread(nullptr),
Packit f0b94e
      mEntryCount(0)
Packit f0b94e
#endif
Packit f0b94e
{
Packit f0b94e
  MOZ_GUARD_OBJECT_NOTIFIER_INIT;
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
  // This number was adapted from NSPR.
Packit f0b94e
  static const DWORD sLockSpinCount = 100;
Packit f0b94e
Packit f0b94e
#if defined(RELEASE_OR_BETA)
Packit f0b94e
  // Vista and later automatically allocate and subsequently leak a debug info
Packit f0b94e
  // object for each critical section that we allocate unless we tell the
Packit f0b94e
  // system not to do that.
Packit f0b94e
  DWORD flags = CRITICAL_SECTION_NO_DEBUG_INFO;
Packit f0b94e
#else
Packit f0b94e
  DWORD flags = 0;
Packit f0b94e
#endif
Packit f0b94e
  BOOL r =
Packit f0b94e
      InitializeCriticalSectionEx(NativeHandle(mMutex), sLockSpinCount, flags);
Packit f0b94e
  MOZ_RELEASE_ASSERT(r);
Packit f0b94e
#else
Packit f0b94e
  pthread_mutexattr_t attr;
Packit f0b94e
Packit f0b94e
  MOZ_RELEASE_ASSERT(pthread_mutexattr_init(&attr) == 0,
Packit f0b94e
                     "pthread_mutexattr_init failed");
Packit f0b94e
Packit f0b94e
  MOZ_RELEASE_ASSERT(
Packit f0b94e
      pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0,
Packit f0b94e
      "pthread_mutexattr_settype failed");
Packit f0b94e
Packit f0b94e
  MOZ_RELEASE_ASSERT(pthread_mutex_init(&mMutex, &attr) == 0,
Packit f0b94e
                     "pthread_mutex_init failed");
Packit f0b94e
Packit f0b94e
  MOZ_RELEASE_ASSERT(pthread_mutexattr_destroy(&attr) == 0,
Packit f0b94e
                     "pthread_mutexattr_destroy failed");
Packit f0b94e
#endif
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
RecursiveMutex::~RecursiveMutex() {
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
  DeleteCriticalSection(NativeHandle(mMutex));
Packit f0b94e
#else
Packit f0b94e
  MOZ_RELEASE_ASSERT(pthread_mutex_destroy(&mMutex) == 0,
Packit f0b94e
                     "pthread_mutex_destroy failed");
Packit f0b94e
#endif
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
void RecursiveMutex::LockInternal() {
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
  EnterCriticalSection(NativeHandle(mMutex));
Packit f0b94e
#else
Packit f0b94e
  MOZ_RELEASE_ASSERT(pthread_mutex_lock(&mMutex) == 0,
Packit f0b94e
                     "pthread_mutex_lock failed");
Packit f0b94e
#endif
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
void RecursiveMutex::UnlockInternal() {
Packit f0b94e
#ifdef XP_WIN
Packit f0b94e
  LeaveCriticalSection(NativeHandle(mMutex));
Packit f0b94e
#else
Packit f0b94e
  MOZ_RELEASE_ASSERT(pthread_mutex_unlock(&mMutex) == 0,
Packit f0b94e
                     "pthread_mutex_unlock failed");
Packit f0b94e
#endif
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
}  // namespace mozilla