forked from BrowserWorks/Waterfox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRecursiveMutex.h
132 lines (110 loc) · 3.3 KB
/
RecursiveMutex.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// A lock that can be acquired multiple times on the same thread.
#ifndef mozilla_RecursiveMutex_h
#define mozilla_RecursiveMutex_h
#include "mozilla/BlockingResourceBase.h"
#include "mozilla/GuardObjects.h"
#ifndef XP_WIN
#include <pthread.h>
#endif
namespace mozilla {
class RecursiveMutex : public BlockingResourceBase
{
public:
explicit RecursiveMutex(const char* aName MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~RecursiveMutex();
#ifdef DEBUG
void Lock();
void Unlock();
#else
void Lock() { LockInternal(); }
void Unlock() { UnlockInternal(); }
#endif
#ifdef DEBUG
/**
* AssertCurrentThreadIn
**/
void AssertCurrentThreadIn();
/**
* AssertNotCurrentThreadIn
**/
void AssertNotCurrentThreadIn()
{
//Not currently implemented. See bug 476536 for discussion.
}
#else
void AssertCurrentThreadIn() {}
void AssertNotCurrentThreadIn() {}
#endif
private:
RecursiveMutex() = delete;
RecursiveMutex(const RecursiveMutex&) = delete;
RecursiveMutex& operator=(const RecursiveMutex&) = delete;
void LockInternal();
void UnlockInternal();
#ifdef DEBUG
PRThread* mOwningThread;
size_t mEntryCount;
#endif
#if !defined(XP_WIN)
pthread_mutex_t mMutex;
#else
// We eschew including windows.h and using CRITICAL_SECTION here so that files
// including us don't also pull in windows.h. Just use a type that's big
// enough for CRITICAL_SECTION, and we'll fix it up later.
void* mMutex[6];
#endif
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class MOZ_RAII RecursiveMutexAutoLock
{
public:
explicit RecursiveMutexAutoLock(RecursiveMutex& aRecursiveMutex
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mRecursiveMutex(&aRecursiveMutex)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
NS_ASSERTION(mRecursiveMutex, "null mutex");
mRecursiveMutex->Lock();
}
~RecursiveMutexAutoLock(void)
{
mRecursiveMutex->Unlock();
}
private:
RecursiveMutexAutoLock() = delete;
RecursiveMutexAutoLock(const RecursiveMutexAutoLock&) = delete;
RecursiveMutexAutoLock& operator=(const RecursiveMutexAutoLock&) = delete;
static void* operator new(size_t) CPP_THROW_NEW;
mozilla::RecursiveMutex* mRecursiveMutex;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class MOZ_RAII RecursiveMutexAutoUnlock
{
public:
explicit RecursiveMutexAutoUnlock(RecursiveMutex& aRecursiveMutex
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mRecursiveMutex(&aRecursiveMutex)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
NS_ASSERTION(mRecursiveMutex, "null mutex");
mRecursiveMutex->Unlock();
}
~RecursiveMutexAutoUnlock(void)
{
mRecursiveMutex->Lock();
}
private:
RecursiveMutexAutoUnlock() = delete;
RecursiveMutexAutoUnlock(const RecursiveMutexAutoUnlock&) = delete;
RecursiveMutexAutoUnlock& operator=(const RecursiveMutexAutoUnlock&) = delete;
static void* operator new(size_t) CPP_THROW_NEW;
mozilla::RecursiveMutex* mRecursiveMutex;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
} // namespace mozilla
#endif // mozilla_RecursiveMutex_h