Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / dep / src / zthread / posix / ConditionRecursiveLock.h
bloba46ed35548c383458a24de1f7242e91942f2945a
1 /*
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 "zthread/NonCopyable.h"
27 #include <pthread.h>
28 #include <errno.h>
29 #include <assert.h>
31 namespace ZThread {
33 /**
34 * @class FastRecursiveLock
36 * @author Eric Crahen <http://www.code-foo.com>
37 * @date <2003-07-16T23:28:37-0400>
38 * @version 2.2.0
40 * This is an implementation of a FastRecursiveLock for any vannila
41 * POSIX system. It is based on a condition variable and a mutex;
42 * because of this it is important to not that its waiting properties
43 * are not the same as other mutex implementations that generally
44 * based on spin locks. Under high contention, this implementation may
45 * be preferable to a spin lock, although refactoring the design of
46 * code that puts a mutex under alot of preasure may be worth investigating.
47 */
48 class FastRecursiveLock : private NonCopyable {
50 //! Serialize state
51 pthread_mutex_t _mtx;
53 //! Wait for lock
54 pthread_cond_t _cond;
56 //! Owner
57 pthread_t _owner;
59 //! Count
60 volatile unsigned int _count;
62 public:
64 inline FastRecursiveLock() : _owner(0), _count(0) {
66 pthread_mutex_init(&_mtx, 0);
67 if(pthread_cond_init(&_cond, 0) != 0) {
68 assert(0);
73 inline ~FastRecursiveLock() {
75 pthread_mutex_destroy(&_mtx);
76 if(pthread_cond_destroy(&_cond) != 0) {
77 assert(0);
82 inline void acquire() {
84 pthread_t self = pthread_self();
85 pthread_mutex_lock(&_mtx);
87 // If the caller does not own the lock, wait until there is no owner
88 if(_owner != 0 && !pthread_equal(_owner, self)) {
90 int status = 0;
91 do { // ignore signals
92 status = pthread_cond_wait(&_cond, &_mtx);
93 } while(status == EINTR && _owner == 0);
97 _owner = self;
98 _count++;
100 pthread_mutex_unlock(&_mtx);
104 inline bool tryAcquire(unsigned long timeout=0) {
106 pthread_t self = pthread_self();
107 pthread_mutex_lock(&_mtx);
109 // If the caller owns the lock, or there is no owner update the count
110 bool success = (_owner == 0 || pthread_equal(_owner, self));
111 if(success) {
113 _owner = self;
114 _count++;
118 pthread_mutex_unlock(&_mtx);
120 return success;
124 inline void release() {
126 assert(pthread_equal(_owner, pthread_self()));
128 pthread_mutex_lock(&_mtx);
129 if(--_count == 0) {
131 _owner = 0;
132 pthread_cond_signal(&_cond);
136 pthread_mutex_unlock(&_mtx);
141 }; /* FastRecursiveLock */
144 } // namespace ZThread
146 #endif