Mutex.h
1/*
2 * Copyright (C) 2005-2008 by Marc Boris Duerner
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * As a special exception, you may use this file as part of a free
10 * software library without restriction. Specifically, if other files
11 * instantiate templates or use macros or inline functions from this
12 * file, or you compile this file and link it with other files to
13 * produce an executable, this file does not by itself cause the
14 * resulting executable to be covered by the GNU General Public
15 * License. This exception does not however invalidate any other
16 * reasons why the executable file might be covered by the GNU Library
17 * General Public License.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#ifndef Pt_System_Mutex_h
30#define Pt_System_Mutex_h
31
32#include <Pt/Atomicity.h>
33#include <Pt/NonCopyable.h>
34#include <Pt/System/Api.h>
35#include <Pt/System/Thread.h>
36
37namespace Pt {
38
39namespace System {
40
72class PT_SYSTEM_API Mutex : private NonCopyable
73{
74 private:
75 class MutexImpl* _impl;
76
77 public:
80
87
95 void lock();
96
102 bool tryLock();
103
105 void unlock();
106
113
115 MutexImpl& impl()
116 { return *_impl; }
117};
118
126class MutexLock : private NonCopyable
127{
128 public:
136 MutexLock(Mutex& m, bool doLock = true, bool isLocked = false)
137 : _mutex(m)
138 , _isLocked(isLocked)
139 {
140 if(doLock)
141 this->lock();
142 }
143
146 {
147 if(_isLocked)
148 _mutex.unlockNoThrow();
149 }
150
153 void lock()
154 {
155 if(!_isLocked)
156 {
157 _mutex.lock();
158 _isLocked = true;
159 }
160 }
161
163 void unlock()
164 {
165 if(_isLocked)
166 {
167 _mutex.unlock();
168 _isLocked = false;
169 }
170 }
171
174 { return _mutex; }
175
177 const Mutex& mutex() const
178 { return _mutex; }
179
180 private:
181 Mutex& _mutex;
182 bool _isLocked;
183};
184
189class PT_SYSTEM_API RecursiveMutex : private NonCopyable
190{
191 private:
192 class MutexImpl* _impl;
193
194 public:
197
200
202 void lock();
203
205 bool tryLock();
206
213 void unlock();
214
216 bool unlockNoThrow();
217};
218
224{
225 public:
233 RecursiveLock(RecursiveMutex& m, bool doLock = true, bool isLocked = false)
234 : _mutex(m)
235 , _isLocked(isLocked)
236 {
237 if(doLock)
238 this->lock();
239 }
240
243 {
244 if(_isLocked)
245 _mutex.unlockNoThrow();
246 }
247
249 void lock()
250 {
251 if(!_isLocked)
252 {
253 _mutex.lock();
254 _isLocked = true;
255 }
256 }
257
259 void unlock()
260 {
261 if(_isLocked)
262 {
263 _mutex.unlock();
264 _isLocked = false;
265 }
266 }
267
270 { return _mutex; }
271
273 const RecursiveMutex& mutex() const
274 { return _mutex; }
275
276 private:
277 RecursiveMutex& _mutex;
278 bool _isLocked;
279};
280
285class PT_SYSTEM_API ReadWriteMutex : private NonCopyable
286{
287 public:
290
293
299 void readLock();
300
308
315 void writeLock();
316
324
326 void unlock();
327
329 bool unlockNoThrow();
330
331 private:
333 class ReadWriteMutexImpl* _impl;
334};
335
340class ReadLock : private NonCopyable
341{
342 public:
350 ReadLock(ReadWriteMutex& m, bool doLock = true, bool isLocked = false)
351 : _mutex(m)
352 , _locked(isLocked)
353 {
354 if(doLock)
355 this->lock();
356 }
357
360 {
361 if(_locked)
362 _mutex.unlockNoThrow();
363 }
364
366 void lock()
367 {
368 if( ! _locked )
369 {
370 _mutex.readLock();
371 _locked = true;
372 }
373 }
374
376 void unlock()
377 {
378 if( _locked)
379 {
380 _mutex.unlock();
381 _locked = false;
382 }
383 }
384
387 { return _mutex; }
388
389 private:
390 ReadWriteMutex& _mutex;
391 bool _locked;
392};
393
398class WriteLock : private NonCopyable
399{
400 public:
408 WriteLock(ReadWriteMutex& m, bool doLock = true, bool isLocked = false)
409 : _mutex(m)
410 , _locked(isLocked)
411 {
412 if(doLock)
413 this->lock();
414 }
415
418 {
419 if(_locked)
420 _mutex.unlockNoThrow();
421 }
422
424 void lock()
425 {
426 if( ! _locked )
427 {
428 _mutex.writeLock();
429 _locked = true;
430 }
431 }
432
434 void unlock()
435 {
436 if( _locked)
437 {
438 _mutex.unlock();
439 _locked = false;
440 }
441 }
442
445 { return _mutex; }
446
447 private:
448 ReadWriteMutex& _mutex;
449 bool _locked;
450};
451
452
464class SpinMutex : private NonCopyable
465{
466 public:
469 : _count(0)
470 {}
471
474 {}
475
484 inline void lock()
485 {
486 // busy loop until unlock
487 while( atomicCompareExchange(_count, 1, 0) )
488 {
490 }
491 }
492
498 bool tryLock()
499 {
500 return ! atomicCompareExchange(_count, 1, 0);
501 }
502
504 void unlock()
505 {
506 // set unlocked
507 atomicExchange(_count, 0);
508 }
509
511 bool testIsLocked() const
512 { return atomicGet(const_cast<volatile Pt::atomic_t&>(_count)) != 0; }
513
514 private:
515 volatile Pt::atomic_t _count;
516};
517
522class SpinLock : private NonCopyable
523{
524 public:
532 SpinLock(SpinMutex& m, bool doLock = true, bool isLocked = false)
533 : _mutex(m)
534 , _locked(isLocked)
535 {
536 if(doLock)
537 this->lock();
538 }
539
542 {
543 if(_locked)
544 this->unlock();
545 }
546
548 void lock()
549 {
550 if( ! _locked )
551 {
552 _mutex.lock();
553 _locked = true;
554 }
555 }
556
558 void unlock()
559 {
560 if( _locked)
561 {
562 _mutex.unlock();
563 _locked = false;
564 }
565 }
566
567 private:
568 SpinMutex& _mutex;
569 bool _locked;
570};
571
572} // namespace System
573
574} // namespace Pt
575
576#endif // Pt_System_Mutex_h
NonCopyable()
Default constructor.
Definition NonCopyable.h:63
Mutex & mutex()
Returns the guarded the mutex object.
Definition Mutex.h:173
const Mutex & mutex() const
Returns the guarded the mutex object.
Definition Mutex.h:177
void unlock()
Unlock so that the destructor does not unlock.
Definition Mutex.h:163
void lock()
Lock the mutex.
Definition Mutex.h:153
MutexLock(Mutex &m, bool doLock=true, bool isLocked=false)
Construct to guard a Mutex.
Definition Mutex.h:136
~MutexLock()
Unlocks the mutex unless unlock() was called.
Definition Mutex.h:145
Mutual exclusion device.
Definition Mutex.h:73
~Mutex()
Destructor.
Mutex()
Default constructor.
void unlock()
Unlocks the mutex.
void lock()
Lock the mutex.
bool tryLock()
Tries to lock the mutex.
bool unlockNoThrow()
Unlocks the mutex.
ReadLock(ReadWriteMutex &m, bool doLock=true, bool isLocked=false)
Construct to guard a ReadWriteMutex.
Definition Mutex.h:350
void unlock()
Unlocks the mutex.
Definition Mutex.h:376
~ReadLock()
Unlocks the mutex unless unlock() was called.
Definition Mutex.h:359
void lock()
Locks the mutex.
Definition Mutex.h:366
ReadWriteMutex & mutex()
Returns the guarded the mutex object.
Definition Mutex.h:386
Mutex for concurrent readers or one writer.
Definition Mutex.h:286
void writeLock()
Acquires a write lock.
ReadWriteMutex()
Constructor.
void unlock()
Releases the read or write lock.
bool tryReadLock()
Tries to acquire a read lock.
void readLock()
Acquires a read lock.
bool tryWriteLock()
Tries to acquire a write lock.
RecursiveLock(RecursiveMutex &m, bool doLock=true, bool isLocked=false)
Construct to guard a RecursiveMutex.
Definition Mutex.h:233
void unlock()
Unlocks the mutex.
Definition Mutex.h:259
RecursiveMutex & mutex()
Returns the guarded the mutex object.
Definition Mutex.h:269
void lock()
Locks the mutex.
Definition Mutex.h:249
~RecursiveLock()
Unlocks the mutex unless unlock() was called.
Definition Mutex.h:242
const RecursiveMutex & mutex() const
Returns the guarded the mutex object.
Definition Mutex.h:273
Recursive mutual exclusion device.
Definition Mutex.h:190
RecursiveMutex()
Constructor.
void unlock()
Unlocks the mutex.
void lock()
Locks the mutex.
bool tryLock()
Returns true if the mutex could be locked..
~SpinLock()
Unlocks the mutex unless unlock() was called.
Definition Mutex.h:541
void unlock()
Unlocks the mutex.
Definition Mutex.h:558
SpinLock(SpinMutex &m, bool doLock=true, bool isLocked=false)
Construct to guard a SpinMutex.
Definition Mutex.h:532
void lock()
Locks the mutex.
Definition Mutex.h:548
Spin mutex.
Definition Mutex.h:465
~SpinMutex()
Destructor.
Definition Mutex.h:473
void unlock()
Unlocks the mutex.
Definition Mutex.h:504
SpinMutex()
Default Constructor.
Definition Mutex.h:468
void lock()
Lock the mutex.
Definition Mutex.h:484
bool tryLock()
Tries to acquire a lock.
Definition Mutex.h:498
static void yield()
Yield CPU time.
~WriteLock()
Unlocks the mutex unless unlock() was called.
Definition Mutex.h:417
WriteLock(ReadWriteMutex &m, bool doLock=true, bool isLocked=false)
Construct to guard a ReadWriteMutex.
Definition Mutex.h:408
void unlock()
Unlocks the mutex.
Definition Mutex.h:434
void lock()
Locks the mutex.
Definition Mutex.h:424
ReadWriteMutex & mutex()
Returns the guarded the mutex object.
Definition Mutex.h:444
int atomicCompareExchange(volatile atomic_t &val, int exch, int comp)
Performs an atomic compare-and-exchange operation.
int atomicExchange(volatile atomic_t &val, int exch)
Performs an atomic exchange operation.
int atomicGet(volatile atomic_t &val)
Atomically get a value.
System programming
Definition Connection.h:26
Core module.
Definition Allocator.h:33
Atomic integers to be used with atomicity functions.
Definition Atomicity.h:52