libfilezilla
rwmutex.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_RWMUTEX_HEADER
2 #define LIBFILEZILLA_RWMUTEX_HEADER
3 
7 #include "libfilezilla.hpp"
8 #include "time.hpp"
9 
10 #ifdef FZ_WINDOWS
11 #include "glue/windows.hpp"
12 #else
13 #include <pthread.h>
14 #endif
15 
16 namespace fz {
17 
23 class FZ_PUBLIC_SYMBOL rwmutex final
24 {
25 public:
26 #ifdef FZ_WINDOWS
27  explicit rwmutex() = default;
28 #else
29  explicit rwmutex()
30  {
31  pthread_rwlock_init(&m_, nullptr);
32  }
33  ~rwmutex()
34  {
35  pthread_rwlock_destroy(&m_);
36  }
37 #endif
38 
39  rwmutex(rwmutex const&) = delete;
40  rwmutex& operator=(rwmutex const&) = delete;
41 
43  void lock_read()
44  {
45 #ifdef FZ_WINDOWS
46  AcquireSRWLockShared(&m_);
47 #else
48  pthread_rwlock_rdlock(&m_);
49 #endif
50  }
51 
52  void lock_write()
53  {
54 #ifdef FZ_WINDOWS
55  AcquireSRWLockExclusive(&m_);
56 #else
57  pthread_rwlock_wrlock(&m_);
58 #endif
59  }
60 
62  void unlock_read()
63  {
64 #ifdef FZ_WINDOWS
65  ReleaseSRWLockShared(&m_);
66 #else
67  pthread_rwlock_unlock(&m_);
68 #endif
69  }
70 
71  void unlock_write()
72  {
73 #ifdef FZ_WINDOWS
74  ReleaseSRWLockExclusive(&m_);
75 #else
76  pthread_rwlock_unlock(&m_);
77 #endif
78  }
79 
80 private:
81  friend class scoped_read_lock;
82  friend class scoped_write_lock;
83 
84 #ifdef FZ_WINDOWS
85  SRWLOCK m_{};
86 #else
87  pthread_rwlock_t m_;
88 #endif
89 };
90 
99 class FZ_PUBLIC_SYMBOL scoped_read_lock final
100 {
101 public:
102  explicit scoped_read_lock(rwmutex& m)
103  : m_(&m.m_)
104  {
105 #ifdef FZ_WINDOWS
106  AcquireSRWLockShared(m_);
107 #else
108  pthread_rwlock_rdlock(m_);
109 #endif
110  }
111 
113  {
114  if (locked_) {
115 #ifdef FZ_WINDOWS
116  ReleaseSRWLockShared(m_);
117 #else
118  pthread_rwlock_unlock(m_);
119 #endif
120  }
121 
122  }
123 
124  scoped_read_lock(scoped_read_lock const&) = delete;
125  scoped_read_lock& operator=(scoped_read_lock const&) = delete;
126 
127  scoped_read_lock(scoped_read_lock&& op) noexcept
128  {
129  m_ = op.m_;
130  op.m_ = 0;
131  locked_ = op.locked_;
132  op.locked_ = false;
133  }
134 
135  scoped_read_lock& operator=(scoped_read_lock&& op) noexcept
136  {
137  if (this != &op) {
138  m_ = op.m_;
139  op.m_ = 0;
140  locked_ = op.locked_;
141  op.locked_ = false;
142  }
143  return *this;
144  }
145 
150  void lock()
151  {
152  locked_ = true;
153 #ifdef FZ_WINDOWS
154  AcquireSRWLockShared(m_);
155 #else
156  pthread_rwlock_rdlock(m_);
157 #endif
158  }
159 
164  void unlock()
165  {
166  locked_ = false;
167 #ifdef FZ_WINDOWS
168  ReleaseSRWLockShared(m_);
169 #else
170  pthread_rwlock_unlock(m_);
171 #endif
172  }
173 
174 private:
175 #ifdef FZ_WINDOWS
176  SRWLOCK* m_;
177 #else
178  pthread_rwlock_t* m_;
179 #endif
180  bool locked_{ true };
181 };
182 
188 class FZ_PUBLIC_SYMBOL scoped_write_lock final
189 {
190 public:
191  explicit scoped_write_lock(rwmutex& m)
192  : m_(&m.m_)
193  {
194 #ifdef FZ_WINDOWS
195  AcquireSRWLockExclusive(m_);
196 #else
197  pthread_rwlock_wrlock(m_);
198 #endif
199  }
200 
202  {
203  if (locked_) {
204 #ifdef FZ_WINDOWS
205  ReleaseSRWLockExclusive(m_);
206 #else
207  pthread_rwlock_unlock(m_);
208 #endif
209  }
210 
211  }
212 
213  scoped_write_lock(scoped_write_lock const&) = delete;
214  scoped_write_lock& operator=(scoped_write_lock const&) = delete;
215 
216  scoped_write_lock(scoped_write_lock&& op) noexcept
217  {
218  m_ = op.m_;
219  op.m_ = 0;
220  locked_ = op.locked_;
221  op.locked_ = false;
222  }
223 
224  scoped_write_lock& operator=(scoped_write_lock&& op) noexcept
225  {
226  if (this != &op) {
227  m_ = op.m_;
228  op.m_ = 0;
229  locked_ = op.locked_;
230  op.locked_ = false;
231  }
232  return *this;
233  }
234 
239  void lock()
240  {
241  locked_ = true;
242 #ifdef FZ_WINDOWS
243  AcquireSRWLockExclusive(m_);
244 #else
245  pthread_rwlock_wrlock(m_);
246 #endif
247  }
248 
253  void unlock()
254  {
255  locked_ = false;
256 #ifdef FZ_WINDOWS
257  ReleaseSRWLockExclusive(m_);
258 #else
259  pthread_rwlock_unlock(m_);
260 #endif
261  }
262 
263 private:
264 #ifdef FZ_WINDOWS
265  SRWLOCK* m_;
266 #else
267  pthread_rwlock_t* m_;
268 #endif
269  bool locked_{ true };
270 };
271 
272 }
273 
274 #endif
Lean rw mutex.
Definition: rwmutex.hpp:24
void lock_read()
Beware, manual locking isn't exception safe, use scoped_lock.
Definition: rwmutex.hpp:43
void unlock_read()
Beware, manual locking isn't exception safe, use scoped_lock.
Definition: rwmutex.hpp:62
A simple scoped read lock.
Definition: rwmutex.hpp:100
void unlock()
Releases the mutex.
Definition: rwmutex.hpp:164
void lock()
Obtains the mutex.
Definition: rwmutex.hpp:150
A simple scoped read lock.
Definition: rwmutex.hpp:189
void unlock()
Releases the mutex.
Definition: rwmutex.hpp:253
void lock()
Obtains the mutex.
Definition: rwmutex.hpp:239
Sets some global macros and further includes string.hpp.
The namespace used by libfilezilla.
Definition: apply.hpp:17
Assorted classes dealing with time.