Bug 1867190 - Initialise the PHC allocate delay later r=glandium
[gecko.git] / xpcom / threads / RecursiveMutex.h
blobdde21c9a351d173e73369c923bd5a47142896565
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/. */
7 // A lock that can be acquired multiple times on the same thread.
9 #ifndef mozilla_RecursiveMutex_h
10 #define mozilla_RecursiveMutex_h
12 #include "mozilla/ThreadSafety.h"
13 #include "mozilla/BlockingResourceBase.h"
15 #ifndef XP_WIN
16 # include <pthread.h>
17 #endif
19 namespace mozilla {
21 class MOZ_CAPABILITY("recursive mutex") RecursiveMutex
22 : public BlockingResourceBase {
23 public:
24 explicit RecursiveMutex(const char* aName);
25 ~RecursiveMutex();
27 #ifdef DEBUG
28 void Lock() MOZ_CAPABILITY_ACQUIRE();
29 void Unlock() MOZ_CAPABILITY_RELEASE();
30 #else
31 void Lock() MOZ_CAPABILITY_ACQUIRE() { LockInternal(); }
32 void Unlock() MOZ_CAPABILITY_RELEASE() { UnlockInternal(); }
33 #endif
35 #ifdef DEBUG
36 /**
37 * AssertCurrentThreadIn
38 **/
39 void AssertCurrentThreadIn() const MOZ_ASSERT_CAPABILITY(this);
40 /**
41 * AssertNotCurrentThreadIn
42 **/
43 void AssertNotCurrentThreadIn() const MOZ_EXCLUDES(this) {
44 // Not currently implemented. See bug 476536 for discussion.
46 #else
47 void AssertCurrentThreadIn() const MOZ_ASSERT_CAPABILITY(this) {}
48 void AssertNotCurrentThreadIn() const MOZ_EXCLUDES(this) {}
49 #endif
51 private:
52 RecursiveMutex() = delete;
53 RecursiveMutex(const RecursiveMutex&) = delete;
54 RecursiveMutex& operator=(const RecursiveMutex&) = delete;
56 void LockInternal();
57 void UnlockInternal();
59 #ifdef DEBUG
60 PRThread* mOwningThread;
61 size_t mEntryCount;
62 #endif
64 #if !defined(XP_WIN)
65 pthread_mutex_t mMutex;
66 #else
67 // We eschew including windows.h and using CRITICAL_SECTION here so that files
68 // including us don't also pull in windows.h. Just use a type that's big
69 // enough for CRITICAL_SECTION, and we'll fix it up later.
70 void* mMutex[6];
71 #endif
74 class MOZ_RAII MOZ_SCOPED_CAPABILITY RecursiveMutexAutoLock {
75 public:
76 explicit RecursiveMutexAutoLock(RecursiveMutex& aRecursiveMutex)
77 MOZ_CAPABILITY_ACQUIRE(aRecursiveMutex)
78 : mRecursiveMutex(&aRecursiveMutex) {
79 NS_ASSERTION(mRecursiveMutex, "null mutex");
80 mRecursiveMutex->Lock();
83 ~RecursiveMutexAutoLock(void) MOZ_CAPABILITY_RELEASE() {
84 mRecursiveMutex->Unlock();
87 private:
88 RecursiveMutexAutoLock() = delete;
89 RecursiveMutexAutoLock(const RecursiveMutexAutoLock&) = delete;
90 RecursiveMutexAutoLock& operator=(const RecursiveMutexAutoLock&) = delete;
91 static void* operator new(size_t) noexcept(true);
93 mozilla::RecursiveMutex* mRecursiveMutex;
96 class MOZ_RAII MOZ_SCOPED_CAPABILITY RecursiveMutexAutoUnlock {
97 public:
98 explicit RecursiveMutexAutoUnlock(RecursiveMutex& aRecursiveMutex)
99 MOZ_SCOPED_UNLOCK_RELEASE(aRecursiveMutex)
100 : mRecursiveMutex(&aRecursiveMutex) {
101 NS_ASSERTION(mRecursiveMutex, "null mutex");
102 mRecursiveMutex->Unlock();
105 ~RecursiveMutexAutoUnlock(void) MOZ_SCOPED_UNLOCK_REACQUIRE() {
106 mRecursiveMutex->Lock();
109 private:
110 RecursiveMutexAutoUnlock() = delete;
111 RecursiveMutexAutoUnlock(const RecursiveMutexAutoUnlock&) = delete;
112 RecursiveMutexAutoUnlock& operator=(const RecursiveMutexAutoUnlock&) = delete;
113 static void* operator new(size_t) noexcept(true);
115 mozilla::RecursiveMutex* mRecursiveMutex;
118 } // namespace mozilla
120 #endif // mozilla_RecursiveMutex_h