comparison Mutex.cpp @ 37:27bab3a16c9a vampy2final

new branch Vampy2final
author fazekasgy
date Mon, 05 Oct 2009 11:28:00 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 37:27bab3a16c9a
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Basic cross-platform mutex abstraction class.
5 This file copyright 2007 Chris Cannam.
6 */
7
8 #include "Mutex.h"
9 #include <iostream>
10
11 #ifndef _WIN32
12 #include <sys/time.h>
13 #include <time.h>
14 #endif
15
16 using std::cerr;
17 using std::endl;
18 using std::string;
19
20 #ifdef _WIN32
21
22 Mutex::Mutex()
23 #ifndef NO_THREAD_CHECKS
24 :
25 m_lockedBy(-1)
26 #endif
27 {
28 m_mutex = CreateMutex(NULL, FALSE, NULL);
29 #ifdef DEBUG_MUTEX
30 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised mutex " << &m_mutex << endl;
31 #endif
32 }
33
34 Mutex::~Mutex()
35 {
36 #ifdef DEBUG_MUTEX
37 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying mutex " << &m_mutex << endl;
38 #endif
39 CloseHandle(m_mutex);
40 }
41
42 void
43 Mutex::lock()
44 {
45 #ifndef NO_THREAD_CHECKS
46 DWORD tid = GetCurrentThreadId();
47 if (m_lockedBy == tid) {
48 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
49 }
50 #endif
51 #ifdef DEBUG_MUTEX
52 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
53 #endif
54 WaitForSingleObject(m_mutex, INFINITE);
55 #ifndef NO_THREAD_CHECKS
56 m_lockedBy = tid;
57 #endif
58 #ifdef DEBUG_MUTEX
59 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
60 #endif
61 }
62
63 void
64 Mutex::unlock()
65 {
66 #ifndef NO_THREAD_CHECKS
67 DWORD tid = GetCurrentThreadId();
68 if (m_lockedBy != tid) {
69 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
70 return;
71 }
72 #endif
73 #ifdef DEBUG_MUTEX
74 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
75 #endif
76 #ifndef NO_THREAD_CHECKS
77 m_lockedBy = -1;
78 #endif
79 ReleaseMutex(m_mutex);
80 }
81
82 bool
83 Mutex::trylock()
84 {
85 #ifndef NO_THREAD_CHECKS
86 DWORD tid = GetCurrentThreadId();
87 #endif
88 DWORD result = WaitForSingleObject(m_mutex, 0);
89 if (result == WAIT_TIMEOUT || result == WAIT_FAILED) {
90 #ifdef DEBUG_MUTEX
91 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
92 #endif
93 return false;
94 } else {
95 #ifndef NO_THREAD_CHECKS
96 m_lockedBy = tid;
97 #endif
98 #ifdef DEBUG_MUTEX
99 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
100 #endif
101 return true;
102 }
103 }
104
105 #else /* !_WIN32 */
106
107 Mutex::Mutex()
108 #ifndef NO_THREAD_CHECKS
109 :
110 m_lockedBy(0),
111 m_locked(false)
112 #endif
113 {
114 pthread_mutex_init(&m_mutex, 0);
115 #ifdef DEBUG_MUTEX
116 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl;
117 #endif
118 }
119
120 Mutex::~Mutex()
121 {
122 #ifdef DEBUG_MUTEX
123 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl;
124 #endif
125 pthread_mutex_destroy(&m_mutex);
126 }
127
128 void
129 Mutex::lock()
130 {
131 #ifndef NO_THREAD_CHECKS
132 pthread_t tid = pthread_self();
133 if (m_locked && m_lockedBy == tid) {
134 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
135 }
136 #endif
137 #ifdef DEBUG_MUTEX
138 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
139 #endif
140 pthread_mutex_lock(&m_mutex);
141 #ifndef NO_THREAD_CHECKS
142 m_lockedBy = tid;
143 m_locked = true;
144 #endif
145 #ifdef DEBUG_MUTEX
146 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
147 #endif
148 }
149
150 void
151 Mutex::unlock()
152 {
153 #ifndef NO_THREAD_CHECKS
154 pthread_t tid = pthread_self();
155 if (!m_locked) {
156 cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl;
157 return;
158 } else if (m_lockedBy != tid) {
159 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
160 return;
161 }
162 #endif
163 #ifdef DEBUG_MUTEX
164 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
165 #endif
166 #ifndef NO_THREAD_CHECKS
167 m_locked = false;
168 #endif
169 pthread_mutex_unlock(&m_mutex);
170 }
171
172 bool
173 Mutex::trylock()
174 {
175 #ifndef NO_THREAD_CHECKS
176 pthread_t tid = pthread_self();
177 #endif
178 if (pthread_mutex_trylock(&m_mutex)) {
179 #ifdef DEBUG_MUTEX
180 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
181 #endif
182 return false;
183 } else {
184 #ifndef NO_THREAD_CHECKS
185 m_lockedBy = tid;
186 m_locked = true;
187 #endif
188 #ifdef DEBUG_MUTEX
189 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
190 #endif
191 return true;
192 }
193 }
194
195 #endif
196
197 MutexLocker::MutexLocker(Mutex *mutex) :
198 m_mutex(mutex)
199 {
200 if (m_mutex) {
201 m_mutex->lock();
202 }
203 }
204
205 MutexLocker::~MutexLocker()
206 {
207 if (m_mutex) {
208 m_mutex->unlock();
209 }
210 }
211