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 __ZTFASTRECURSIVELOCK_H__
24
#define __ZTFASTRECURSIVELOCK_H__
26
#include "../FastLock.h"
27
#include "../ThreadOps.h"
33
* @class FastRecursiveLock
35
* @author Eric Crahen <http://www.code-foo.com>
36
* @date <2003-07-16T23:31:09-0400>
39
* This is a vanilla FastRecursiveLock implementation for a
40
* system that doesn't provide recurisve locks. This implementation
41
* is based on using a pair of mutexes, because of this, it performs
42
* roughly the same as a spin lock would.
44
class FastRecursiveLock : private NonCopyable {
47
FastLock _blockingLock;
56
volatile unsigned int _count;
60
inline FastRecursiveLock() : _owner(ThreadOps::INVALID), _count(0) { }
62
inline ~FastRecursiveLock() {
64
assert(_owner == ThreadOps::INVALID);
71
ThreadOps self(ThreadOps::self());
73
// Try to lock the blocking mutex first
74
bool wasLocked = _blockingLock.tryAcquire();
77
// Otherwise, grab the lock for the state
80
wasLocked = (_owner == self);
89
// Try to be cooperative
91
_blockingLock.acquire();
95
// Serialze access to the state
99
assert(_owner == ThreadOps::INVALID || _owner == self);
104
_stateLock.release();
109
bool tryAcquire(unsigned long timeout = 0) {
111
ThreadOps self(ThreadOps::self());
113
// Try to lock the blocking mutex first
114
bool wasLocked = _blockingLock.tryAcquire();
117
// Otherwise, grab the lock for the state
118
_stateLock.acquire();
120
wasLocked = (_owner == self);
124
_stateLock.release();
130
// Serialze access to the state
131
_stateLock.acquire();
134
assert(_owner == ThreadOps::INVALID || _owner == self);
139
_stateLock.release();
148
// Assume that release is only used by the owning thread, as it
151
assert(_owner == ThreadOps::self());
153
_stateLock.acquire();
155
// If the lock was owned and the count has reached 0, give up
156
// ownership and release the blocking lock
159
_owner = ThreadOps::INVALID;
160
_blockingLock.release();
164
_stateLock.release();
169
}; /* FastRecursiveLock */
171
} // namespace ZThread