Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/RWLock.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
// An interface for read-write locks.
8
9
#ifndef mozilla_RWLock_h
10
#define mozilla_RWLock_h
11
12
#include "mozilla/Assertions.h"
13
#include "mozilla/BlockingResourceBase.h"
14
#include "mozilla/GuardObjects.h"
15
16
#ifndef XP_WIN
17
#include <pthread.h>
18
#endif
19
20
namespace mozilla {
21
22
// A RWLock is similar to a Mutex, but whereas a Mutex permits only a single
23
// reader thread or a single writer thread to access a piece of data, a
24
// RWLock distinguishes between readers and writers: you may have multiple
25
// reader threads concurrently accessing a piece of data or a single writer
26
// thread.  This difference should guide your usage of RWLock: if you are not
27
// reading the data from multiple threads simultaneously or you are writing
28
// to the data roughly as often as read from it, then Mutex will suit your
29
// purposes just fine.
30
//
31
// You should be using the AutoReadLock and AutoWriteLock classes, below,
32
// for RAII read locking and write locking, respectively.  If you really must
33
// take a read lock manually, call the ReadLock method; to relinquish that
34
// read lock, call the ReadUnlock method.  Similarly, WriteLock and WriteUnlock
35
// perform the same operations, but for write locks.
36
//
37
// It is unspecified what happens when a given thread attempts to acquire the
38
// same lock in multiple ways; some underlying implementations of RWLock do
39
// support acquiring a read lock multiple times on a given thread, but you
40
// should not rely on this behavior.
41
//
42
// It is unspecified whether RWLock gives priority to waiting readers or
43
// a waiting writer when unlocking.
44
class RWLock : public BlockingResourceBase
45
{
46
public:
47
  explicit RWLock(const char* aName);
48
49
  // Windows rwlocks don't need any special handling to be destroyed, but
50
  // POSIX ones do.
51
#ifdef XP_WIN
52
  ~RWLock() = default;
53
#else
54
  ~RWLock();
55
#endif
56
57
#ifdef DEBUG
58
  bool LockedForWritingByCurrentThread();
59
  void ReadLock();
60
  void ReadUnlock();
61
  void WriteLock();
62
  void WriteUnlock();
63
#else
64
0
  void ReadLock() { ReadLockInternal(); }
65
0
  void ReadUnlock() { ReadUnlockInternal(); }
66
0
  void WriteLock() { WriteLockInternal(); }
67
0
  void WriteUnlock() { WriteUnlockInternal(); }
68
#endif
69
70
private:
71
  void ReadLockInternal();
72
  void ReadUnlockInternal();
73
  void WriteLockInternal();
74
  void WriteUnlockInternal();
75
76
  RWLock() = delete;
77
  RWLock(const RWLock&) = delete;
78
  RWLock& operator=(const RWLock&) = delete;
79
80
#ifndef XP_WIN
81
  pthread_rwlock_t mRWLock;
82
#else
83
  // SRWLock is pointer-sized.  We declare it in such a fashion here to
84
  // avoid pulling in windows.h wherever this header is used.
85
  void* mRWLock;
86
#endif
87
88
#ifdef DEBUG
89
  // We record the owning thread for write locks only.
90
  PRThread* mOwningThread;
91
#endif
92
};
93
94
// Read lock and unlock a RWLock with RAII semantics.  Much preferred to bare
95
// calls to ReadLock() and ReadUnlock().
96
class MOZ_RAII AutoReadLock final
97
{
98
public:
99
  explicit AutoReadLock(RWLock& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
100
    : mLock(&aLock)
101
0
  {
102
0
    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
103
0
    MOZ_ASSERT(mLock, "null lock");
104
0
    mLock->ReadLock();
105
0
  }
106
107
  ~AutoReadLock()
108
0
  {
109
0
    mLock->ReadUnlock();
110
0
  }
111
112
 private:
113
  AutoReadLock() = delete;
114
  AutoReadLock(const AutoReadLock&) = delete;
115
  AutoReadLock& operator=(const AutoReadLock&) = delete;
116
117
  RWLock* mLock;
118
  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
119
};
120
121
// Write lock and unlock a RWLock with RAII semantics.  Much preferred to bare
122
// calls to WriteLock() and WriteUnlock().
123
class MOZ_RAII AutoWriteLock final
124
{
125
public:
126
  explicit AutoWriteLock(RWLock& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
127
    : mLock(&aLock)
128
0
  {
129
0
    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
130
0
    MOZ_ASSERT(mLock, "null lock");
131
0
    mLock->WriteLock();
132
0
  }
133
134
  ~AutoWriteLock()
135
0
  {
136
0
    mLock->WriteUnlock();
137
0
  }
138
139
 private:
140
  AutoWriteLock() = delete;
141
  AutoWriteLock(const AutoWriteLock&) = delete;
142
  AutoWriteLock& operator=(const AutoWriteLock&) = delete;
143
144
  RWLock* mLock;
145
  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
146
};
147
148
} // namespace mozilla
149
150
#endif // mozilla_RWLock_h