libUTL++
RWlock.h
1 #pragma once
2 
4 
5 #include <libutl/host_thread.h>
6 #include <libutl/NamedObjectMI.h>
7 
9 
10 UTL_NS_BEGIN;
11 
13 
14 class Mutex;
15 
17 // RWlock //////////////////////////////////////////////////////////////////////////////////////////
19 
31 
33 class RWlock : public Object, public NamedObjectMI
34 {
37 
38 public:
43  bool haveWriteLock() const;
44 
49  void
50  lock(uint_t mode)
51  {
52  (mode == io_rd) ? rdlock() : wrlock();
53  }
54 
56  void rdlock();
57 
59  void wrlock();
60 
65  bool
67  {
68  return (mode == io_rd) ? tryrdlock() : trywrlock();
69  }
70 
75  bool tryrdlock();
76 
81  bool trywrlock();
82 
84  void unlock();
85 
86 private:
87  void init();
88  void deInit();
89 
90 private:
91 #if UTL_HOST_OS == UTL_OS_MINGW
92  void* _readEvent;
93  Mutex* _writeMutex;
94  volatile long _numReaders;
95  uint_t _mode;
96 #else
97  pthread_rwlock_t _rwlock;
98 #endif
99  thread_handle_t _writeLockOwner;
100  size_t _depth;
101 };
102 
104 // RWlockGuard /////////////////////////////////////////////////////////////////////////////////////
106 
114 
117 {
118 public:
121  : _locked(false)
122  , _rwlock(nullptr)
123  {
124  }
125 
131  RWlockGuard(RWlock* rwlock, uint_t mode)
132  : _locked(false)
133  , _rwlock(rwlock)
134  {
135  _lock(mode);
136  }
137 
140  {
141  unlock();
142  }
143 
149  void
150  lock(RWlock* rwlock, uint_t mode)
151  {
152  unlock();
153  _rwlock = rwlock;
154  _lock(mode);
155  }
156 
161  void
162  lock(uint_t mode)
163  {
164  (mode == io_rd) ? rdlock() : wrlock();
165  }
166 
171  void
172  rdlock(RWlock* rwlock)
173  {
174  unlock();
175  _rwlock = rwlock;
176  _rdlock();
177  }
178 
183  void
184  wrlock(RWlock* rwlock)
185  {
186  unlock();
187  _rwlock = rwlock;
188  _wrlock();
189  }
190 
192  void
194  {
195  unlock();
196  _rdlock();
197  }
198 
200  void
202  {
203  unlock();
204  _wrlock();
205  }
206 
213  bool
214  trylock(RWlock* rwlock, uint_t mode)
215  {
216  unlock();
217  _rwlock = rwlock;
218  return _trylock(mode);
219  }
220 
226  bool
228  {
229  return (mode == io_rd) ? tryrdlock() : trywrlock();
230  }
231 
237  bool
238  tryrdlock(RWlock* rwlock)
239  {
240  unlock();
241  _rwlock = rwlock;
242  return _tryrdlock();
243  }
244 
250  bool
251  trywrlock(RWlock* rwlock)
252  {
253  unlock();
254  _rwlock = rwlock;
255  return _trywrlock();
256  }
257 
262  bool
264  {
265  unlock();
266  return _tryrdlock();
267  }
268 
273  bool
275  {
276  unlock();
277  return _trywrlock();
278  }
279 
281  inline void
283  {
284  if (_locked) _unlock();
285  }
286 
287 private:
288  void
289  _lock(uint_t mode)
290  {
291  (mode == io_rd) ? _rdlock() : _wrlock();
292  }
293 
294  void
295  _rdlock()
296  {
297  ASSERTD(_rwlock != nullptr);
298  ASSERTD(!_locked);
299  _rwlock->rdlock();
300  _locked = true;
301  }
302 
303  void
304  _wrlock()
305  {
306  ASSERTD(_rwlock != nullptr);
307  ASSERTD(!_locked);
308  _rwlock->wrlock();
309  _locked = true;
310  }
311 
312  bool
313  _trylock(uint_t mode)
314  {
315  return (mode == io_rd) ? _tryrdlock() : _trywrlock();
316  }
317 
318  bool
319  _tryrdlock()
320  {
321  ASSERTD(_rwlock != nullptr);
322  ASSERTD(!_locked);
323  if (_rwlock->tryrdlock()) _locked = true;
324  return _locked;
325  }
326 
327  bool
328  _trywrlock()
329  {
330  ASSERTD(_rwlock != nullptr);
331  ASSERTD(!_locked);
332  if (_rwlock->trywrlock()) _locked = true;
333  return _locked;
334  }
335 
336  void
337  _unlock()
338  {
339  ASSERTD(_rwlock != nullptr);
340  ASSERTD(_locked);
341  _rwlock->unlock();
342  _locked = false;
343  }
344 
345 private:
346  bool _locked;
347  RWlock* _rwlock;
348 };
349 
351 
352 UTL_NS_END;
Named object mix-in.
Definition: NamedObjectMI.h:24
bool trylock(RWlock *rwlock, uint_t mode)
Try to acquire read- or write-lock (without blocking).
Definition: RWlock.h:214
Read/write lock.
Definition: RWlock.h:33
bool trywrlock(RWlock *rwlock)
Try to acquire write-lock (without blocking).
Definition: RWlock.h:251
void rdlock()
Acquire read-lock.
Definition: RWlock.h:193
void deInit()
De-initialize UTL++.
#define UTL_CLASS_DECL(DC, BC)
Declaration of standard UTL++ functionality for a non-template class.
Definition: macros.h:688
bool trylock(uint_t mode)
Try to acquire read- or write-lock (without blocking).
Definition: RWlock.h:66
MUTual EXclusion device.
Definition: Mutex.h:27
bool tryrdlock(RWlock *rwlock)
Try to acquire read-lock (without blocking).
Definition: RWlock.h:238
void wrlock()
Acquire write-lock.
Definition: RWlock.h:201
read
Definition: util.h:58
RWlockGuard()
Default constructor.
Definition: RWlock.h:120
bool tryrdlock()
Try to acquire read-lock (without blocking).
Definition: RWlock.h:263
Acquire/release a RWlock RAII-style.
Definition: RWlock.h:116
void rdlock(RWlock *rwlock)
Acquire read-lock.
Definition: RWlock.h:172
unsigned int uint_t
Unsigned integer.
Definition: types.h:59
void lock(uint_t mode)
Acquire read- or write-lock.
Definition: RWlock.h:162
void lock(uint_t mode)
Acquire read- or write-lock.
Definition: RWlock.h:50
bool trylock(uint_t mode)
Try to acquire read- or write-lock (without blocking).
Definition: RWlock.h:227
~RWlockGuard()
Destructor.
Definition: RWlock.h:139
RWlockGuard(RWlock *rwlock, uint_t mode)
Constructor.
Definition: RWlock.h:131
#define UTL_CLASS_NO_COPY
Declare that a class cannot do copy().
Definition: macros.h:358
bool trywrlock()
Try to acquire write-lock (without blocking).
Definition: RWlock.h:274
void unlock()
Release the lock.
Definition: RWlock.h:282
void wrlock(RWlock *rwlock)
Acquire write-lock.
Definition: RWlock.h:184
Root of UTL++ class hierarchy.
Definition: Object.h:52
void lock(RWlock *rwlock, uint_t mode)
Acquire read- or write-lock.
Definition: RWlock.h:150
void init()
Initialize UTL++.
#define ASSERTD
Do an assertion in DEBUG mode only.