Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/RecursiveMutex.h
Line
Count
Source (jump to first uncovered line)
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
// A lock that can be acquired multiple times on the same thread.
8
9
#ifndef mozilla_RecursiveMutex_h
10
#define mozilla_RecursiveMutex_h
11
12
#include "mozilla/BlockingResourceBase.h"
13
#include "mozilla/GuardObjects.h"
14
15
#ifndef XP_WIN
16
#include <pthread.h>
17
#endif
18
19
namespace mozilla {
20
21
class RecursiveMutex : public BlockingResourceBase
22
{
23
public:
24
  explicit RecursiveMutex(const char* aName MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
25
  ~RecursiveMutex();
26
27
#ifdef DEBUG
28
  void Lock();
29
  void Unlock();
30
#else
31
0
  void Lock() { LockInternal(); }
32
0
  void Unlock() { UnlockInternal(); }
33
#endif
34
35
#ifdef DEBUG
36
  /**
37
   * AssertCurrentThreadIn
38
   **/
39
  void AssertCurrentThreadIn();
40
  /**
41
   * AssertNotCurrentThreadIn
42
   **/
43
  void AssertNotCurrentThreadIn()
44
  {
45
    //Not currently implemented. See bug 476536 for discussion.
46
  }
47
#else
48
0
  void AssertCurrentThreadIn() {}
49
0
  void AssertNotCurrentThreadIn() {}
50
#endif
51
52
private:
53
  RecursiveMutex() = delete;
54
  RecursiveMutex(const RecursiveMutex&) = delete;
55
  RecursiveMutex& operator=(const RecursiveMutex&) = delete;
56
57
  void LockInternal();
58
  void UnlockInternal();
59
60
#ifdef DEBUG
61
  PRThread* mOwningThread;
62
  size_t mEntryCount;
63
#endif
64
65
#if !defined(XP_WIN)
66
  pthread_mutex_t mMutex;
67
#else
68
  // We eschew including windows.h and using CRITICAL_SECTION here so that files
69
  // including us don't also pull in windows.h.  Just use a type that's big
70
  // enough for CRITICAL_SECTION, and we'll fix it up later.
71
  void* mMutex[6];
72
#endif
73
  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
74
};
75
76
class MOZ_RAII RecursiveMutexAutoLock
77
{
78
public:
79
  explicit RecursiveMutexAutoLock(RecursiveMutex& aRecursiveMutex
80
                                  MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
81
    : mRecursiveMutex(&aRecursiveMutex)
82
0
  {
83
0
    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
84
0
    NS_ASSERTION(mRecursiveMutex, "null mutex");
85
0
    mRecursiveMutex->Lock();
86
0
  }
87
88
  ~RecursiveMutexAutoLock(void)
89
0
  {
90
0
    mRecursiveMutex->Unlock();
91
0
  }
92
93
private:
94
  RecursiveMutexAutoLock() = delete;
95
  RecursiveMutexAutoLock(const RecursiveMutexAutoLock&) = delete;
96
  RecursiveMutexAutoLock& operator=(const RecursiveMutexAutoLock&) = delete;
97
  static void* operator new(size_t) CPP_THROW_NEW;
98
99
  mozilla::RecursiveMutex* mRecursiveMutex;
100
  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
101
};
102
103
class MOZ_RAII RecursiveMutexAutoUnlock
104
{
105
public:
106
  explicit RecursiveMutexAutoUnlock(RecursiveMutex& aRecursiveMutex
107
                                    MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
108
    : mRecursiveMutex(&aRecursiveMutex)
109
0
  {
110
0
    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
111
0
    NS_ASSERTION(mRecursiveMutex, "null mutex");
112
0
    mRecursiveMutex->Unlock();
113
0
  }
114
115
  ~RecursiveMutexAutoUnlock(void)
116
0
  {
117
0
    mRecursiveMutex->Lock();
118
0
  }
119
120
private:
121
  RecursiveMutexAutoUnlock() = delete;
122
  RecursiveMutexAutoUnlock(const RecursiveMutexAutoUnlock&) = delete;
123
  RecursiveMutexAutoUnlock& operator=(const RecursiveMutexAutoUnlock&) = delete;
124
  static void* operator new(size_t) CPP_THROW_NEW;
125
126
  mozilla::RecursiveMutex* mRecursiveMutex;
127
  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
128
};
129
130
} // namespace mozilla
131
132
#endif // mozilla_RecursiveMutex_h