2 * Copyright (c) 2005, Eric Crahen
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is furnished
9 * to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #ifndef __ZTFAIRREADWRITELOCK_H__
24 #define __ZTFAIRREADWRITELOCK_H__
26 #include "zthread/ReadWriteLock.h"
27 #include "zthread/Condition.h"
28 #include "zthread/Guard.h"
29 #include "zthread/Mutex.h"
34 * @class FairReadWriteLock
36 * @author Eric Crahen <http://www.code-foo.com>
37 * @date <2003-07-16T10:26:25-0400>
40 * A FairReadWriteLock maintains a balance between the order read-only access
41 * and read-write access is allowed. Threads contending for the pair of Lockable
42 * objects this ReadWriteLock provides will gain access to the locks in FIFO order.
46 class FairReadWriteLock
: public ReadWriteLock
{
51 volatile int _readers
;
54 class ReadLock
: public Lockable
{
56 FairReadWriteLock
& _rwlock
;
60 ReadLock(FairReadWriteLock
& rwlock
) : _rwlock(rwlock
) {}
62 virtual ~ReadLock() {}
64 virtual void acquire() {
66 Guard
<Mutex
> g(_rwlock
._lock
);
71 virtual bool tryAcquire(unsigned long timeout
) {
73 if(!_rwlock
._lock
.tryAcquire(timeout
))
77 _rwlock
._lock
.release();
82 virtual void release() {
84 Guard
<Mutex
> g(_rwlock
._lock
);
87 if(_rwlock
._readers
== 0)
88 _rwlock
._cond
.signal();
95 class WriteLock
: public Lockable
{
97 FairReadWriteLock
& _rwlock
;
101 WriteLock(FairReadWriteLock
& rwlock
) : _rwlock(rwlock
) {}
103 virtual ~WriteLock() {}
105 virtual void acquire() {
107 _rwlock
._lock
.acquire();
111 while(_rwlock
._readers
> 0)
112 _rwlock
._cond
.wait();
116 _rwlock
._lock
.release();
123 virtual bool tryAcquire(unsigned long timeout
) {
125 if(!_rwlock
._lock
.tryAcquire(timeout
))
130 while(_rwlock
._readers
> 0)
131 _rwlock
._cond
.wait(timeout
);
135 _rwlock
._lock
.release();
144 virtual void release() {
145 _rwlock
._lock
.release();
150 friend class ReadLock
;
151 friend class WriteLock
;
159 * Create a BiasedReadWriteLock
161 * @exception Initialization_Exception thrown if resources could not be
162 * allocated for this object.
164 FairReadWriteLock() : _cond(_lock
), _readers(0), _rlock(*this), _wlock(*this) {}
166 //! Destroy this ReadWriteLock
167 virtual ~FairReadWriteLock() {}
170 * @see ReadWriteLock::getReadLock()
172 virtual Lockable
& getReadLock() { return _rlock
; }
175 * @see ReadWriteLock::getWriteLock()
177 virtual Lockable
& getWriteLock() { return _wlock
; }
181 }; // __ZTFAIRREADWRITELOCK_H__