c@287
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
c@287
|
2
|
c@287
|
3 /*
|
c@287
|
4 QM DSP Library
|
c@287
|
5
|
c@287
|
6 Centre for Digital Music, Queen Mary, University of London.
|
c@287
|
7 This file copyright Chris Cannam, used with permission.
|
c@287
|
8 */
|
c@287
|
9
|
c@287
|
10 #include "Thread.h"
|
c@287
|
11
|
c@287
|
12 #include <iostream>
|
c@287
|
13 #include <cstdlib>
|
c@287
|
14
|
c@287
|
15 #ifdef USE_PTHREADS
|
c@287
|
16 #include <sys/time.h>
|
c@287
|
17 #include <time.h>
|
c@287
|
18 #endif
|
c@287
|
19
|
c@287
|
20 using std::cerr;
|
c@287
|
21 using std::endl;
|
c@287
|
22 using std::string;
|
c@287
|
23
|
c@287
|
24 #ifdef _WIN32
|
c@287
|
25
|
c@287
|
26 Thread::Thread() :
|
c@287
|
27 m_id(0),
|
c@287
|
28 m_extant(false)
|
c@287
|
29 {
|
c@287
|
30 #ifdef DEBUG_THREAD
|
c@287
|
31 cerr << "THREAD DEBUG: Created thread object " << this << endl;
|
c@287
|
32 #endif
|
c@287
|
33 }
|
c@287
|
34
|
c@287
|
35 Thread::~Thread()
|
c@287
|
36 {
|
c@287
|
37 #ifdef DEBUG_THREAD
|
c@287
|
38 cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
|
c@287
|
39 #endif
|
c@287
|
40 if (m_extant) {
|
c@287
|
41 WaitForSingleObject(m_id, INFINITE);
|
c@287
|
42 }
|
c@287
|
43 #ifdef DEBUG_THREAD
|
c@287
|
44 cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
|
c@287
|
45 #endif
|
c@287
|
46 }
|
c@287
|
47
|
c@287
|
48 void
|
c@287
|
49 Thread::start()
|
c@287
|
50 {
|
c@287
|
51 m_id = CreateThread(NULL, 0, staticRun, this, 0, 0);
|
c@287
|
52 if (!m_id) {
|
c@287
|
53 cerr << "ERROR: thread creation failed" << endl;
|
c@287
|
54 exit(1);
|
c@287
|
55 } else {
|
c@287
|
56 #ifdef DEBUG_THREAD
|
c@287
|
57 cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
|
c@287
|
58 #endif
|
c@287
|
59 m_extant = true;
|
c@287
|
60 }
|
c@287
|
61 }
|
c@287
|
62
|
c@287
|
63 void
|
c@287
|
64 Thread::wait()
|
c@287
|
65 {
|
c@287
|
66 if (m_extant) {
|
c@287
|
67 #ifdef DEBUG_THREAD
|
c@287
|
68 cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
69 #endif
|
c@287
|
70 WaitForSingleObject(m_id, INFINITE);
|
c@287
|
71 #ifdef DEBUG_THREAD
|
c@287
|
72 cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
73 #endif
|
c@287
|
74 m_extant = false;
|
c@287
|
75 }
|
c@287
|
76 }
|
c@287
|
77
|
c@287
|
78 Thread::Id
|
c@287
|
79 Thread::id()
|
c@287
|
80 {
|
c@287
|
81 return m_id;
|
c@287
|
82 }
|
c@287
|
83
|
c@287
|
84 bool
|
c@287
|
85 Thread::threadingAvailable()
|
c@287
|
86 {
|
c@287
|
87 return true;
|
c@287
|
88 }
|
c@287
|
89
|
c@287
|
90 DWORD
|
c@287
|
91 Thread::staticRun(LPVOID arg)
|
c@287
|
92 {
|
c@287
|
93 Thread *thread = static_cast<Thread *>(arg);
|
c@287
|
94 #ifdef DEBUG_THREAD
|
c@287
|
95 cerr << "THREAD DEBUG: " << (void *)GetCurrentThreadId() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
|
c@287
|
96 #endif
|
c@287
|
97 thread->run();
|
c@287
|
98 return 0;
|
c@287
|
99 }
|
c@287
|
100
|
c@287
|
101 Mutex::Mutex()
|
c@287
|
102 #ifndef NO_THREAD_CHECKS
|
c@287
|
103 :
|
c@287
|
104 m_lockedBy(-1)
|
c@287
|
105 #endif
|
c@287
|
106 {
|
c@287
|
107 m_mutex = CreateMutex(NULL, FALSE, NULL);
|
c@287
|
108 #ifdef DEBUG_MUTEX
|
c@287
|
109 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised mutex " << &m_mutex << endl;
|
c@287
|
110 #endif
|
c@287
|
111 }
|
c@287
|
112
|
c@287
|
113 Mutex::~Mutex()
|
c@287
|
114 {
|
c@287
|
115 #ifdef DEBUG_MUTEX
|
c@287
|
116 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying mutex " << &m_mutex << endl;
|
c@287
|
117 #endif
|
c@287
|
118 CloseHandle(m_mutex);
|
c@287
|
119 }
|
c@287
|
120
|
c@287
|
121 void
|
c@287
|
122 Mutex::lock()
|
c@287
|
123 {
|
c@287
|
124 #ifndef NO_THREAD_CHECKS
|
c@287
|
125 DWORD tid = GetCurrentThreadId();
|
c@287
|
126 if (m_lockedBy == tid) {
|
c@287
|
127 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
|
c@287
|
128 }
|
c@287
|
129 #endif
|
c@287
|
130 #ifdef DEBUG_MUTEX
|
c@287
|
131 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
|
c@287
|
132 #endif
|
c@287
|
133 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
134 #ifndef NO_THREAD_CHECKS
|
c@287
|
135 m_lockedBy = tid;
|
c@287
|
136 #endif
|
c@287
|
137 #ifdef DEBUG_MUTEX
|
c@287
|
138 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
|
c@287
|
139 #endif
|
c@287
|
140 }
|
c@287
|
141
|
c@287
|
142 void
|
c@287
|
143 Mutex::unlock()
|
c@287
|
144 {
|
c@287
|
145 #ifndef NO_THREAD_CHECKS
|
c@287
|
146 DWORD tid = GetCurrentThreadId();
|
c@287
|
147 if (m_lockedBy != tid) {
|
c@287
|
148 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
|
c@287
|
149 return;
|
c@287
|
150 }
|
c@287
|
151 #endif
|
c@287
|
152 #ifdef DEBUG_MUTEX
|
c@287
|
153 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
|
c@287
|
154 #endif
|
c@287
|
155 #ifndef NO_THREAD_CHECKS
|
c@287
|
156 m_lockedBy = -1;
|
c@287
|
157 #endif
|
c@287
|
158 ReleaseMutex(m_mutex);
|
c@287
|
159 }
|
c@287
|
160
|
c@287
|
161 bool
|
c@287
|
162 Mutex::trylock()
|
c@287
|
163 {
|
c@287
|
164 #ifndef NO_THREAD_CHECKS
|
c@287
|
165 DWORD tid = GetCurrentThreadId();
|
c@287
|
166 #endif
|
c@287
|
167 DWORD result = WaitForSingleObject(m_mutex, 0);
|
c@287
|
168 if (result == WAIT_TIMEOUT || result == WAIT_FAILED) {
|
c@287
|
169 #ifdef DEBUG_MUTEX
|
c@287
|
170 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
|
c@287
|
171 #endif
|
c@287
|
172 return false;
|
c@287
|
173 } else {
|
c@287
|
174 #ifndef NO_THREAD_CHECKS
|
c@287
|
175 m_lockedBy = tid;
|
c@287
|
176 #endif
|
c@287
|
177 #ifdef DEBUG_MUTEX
|
c@287
|
178 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
|
c@287
|
179 #endif
|
c@287
|
180 return true;
|
c@287
|
181 }
|
c@287
|
182 }
|
c@287
|
183
|
c@287
|
184 Condition::Condition(string name) :
|
c@287
|
185 m_locked(false)
|
c@287
|
186 #ifdef DEBUG_CONDITION
|
c@287
|
187 , m_name(name)
|
c@287
|
188 #endif
|
c@287
|
189 {
|
c@287
|
190 m_mutex = CreateMutex(NULL, FALSE, NULL);
|
c@287
|
191 m_condition = CreateEvent(NULL, FALSE, FALSE, NULL);
|
c@287
|
192 #ifdef DEBUG_CONDITION
|
c@287
|
193 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
194 #endif
|
c@287
|
195 }
|
c@287
|
196
|
c@287
|
197 Condition::~Condition()
|
c@287
|
198 {
|
c@287
|
199 #ifdef DEBUG_CONDITION
|
c@287
|
200 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Destroying condition " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
201 #endif
|
c@287
|
202 if (m_locked) ReleaseMutex(m_mutex);
|
c@287
|
203 CloseHandle(m_condition);
|
c@287
|
204 CloseHandle(m_mutex);
|
c@287
|
205 }
|
c@287
|
206
|
c@287
|
207 void
|
c@287
|
208 Condition::lock()
|
c@287
|
209 {
|
c@287
|
210 if (m_locked) {
|
c@287
|
211 #ifdef DEBUG_CONDITION
|
c@287
|
212 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Already locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
213 #endif
|
c@287
|
214 return;
|
c@287
|
215 }
|
c@287
|
216 #ifdef DEBUG_CONDITION
|
c@287
|
217 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
218 #endif
|
c@287
|
219 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
220 m_locked = true;
|
c@287
|
221 #ifdef DEBUG_CONDITION
|
c@287
|
222 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
223 #endif
|
c@287
|
224 }
|
c@287
|
225
|
c@287
|
226 void
|
c@287
|
227 Condition::unlock()
|
c@287
|
228 {
|
c@287
|
229 if (!m_locked) {
|
c@287
|
230 #ifdef DEBUG_CONDITION
|
c@287
|
231 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
232 #endif
|
c@287
|
233 return;
|
c@287
|
234 }
|
c@287
|
235 #ifdef DEBUG_CONDITION
|
c@287
|
236 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
237 #endif
|
c@287
|
238 m_locked = false;
|
c@287
|
239 ReleaseMutex(m_mutex);
|
c@287
|
240 }
|
c@287
|
241
|
c@287
|
242 void
|
c@287
|
243 Condition::wait(int us)
|
c@287
|
244 {
|
c@287
|
245 if (us == 0) {
|
c@287
|
246
|
c@287
|
247 #ifdef DEBUG_CONDITION
|
c@287
|
248 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
249 #endif
|
c@287
|
250 SignalObjectAndWait(m_mutex, m_condition, INFINITE, FALSE);
|
c@287
|
251 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
252
|
c@287
|
253 } else {
|
c@287
|
254
|
c@287
|
255 DWORD ms = us / 1000;
|
c@287
|
256 if (us > 0 && ms == 0) ms = 1;
|
c@287
|
257
|
c@287
|
258 #ifdef DEBUG_CONDITION
|
c@287
|
259 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
260 #endif
|
c@287
|
261 SignalObjectAndWait(m_mutex, m_condition, ms, FALSE);
|
c@287
|
262 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
263 }
|
c@287
|
264
|
c@287
|
265 #ifdef DEBUG_CONDITION
|
c@287
|
266 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
267 #endif
|
c@287
|
268 }
|
c@287
|
269
|
c@287
|
270 void
|
c@287
|
271 Condition::signal()
|
c@287
|
272 {
|
c@287
|
273 #ifdef DEBUG_CONDITION
|
c@287
|
274 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
275 #endif
|
c@287
|
276 SetEvent(m_condition);
|
c@287
|
277 }
|
c@287
|
278
|
c@287
|
279 #else /* !_WIN32 */
|
c@287
|
280
|
c@287
|
281 #ifdef USE_PTHREADS
|
c@287
|
282
|
c@287
|
283 Thread::Thread() :
|
c@287
|
284 m_id(0),
|
c@287
|
285 m_extant(false)
|
c@287
|
286 {
|
c@287
|
287 #ifdef DEBUG_THREAD
|
c@287
|
288 cerr << "THREAD DEBUG: Created thread object " << this << endl;
|
c@287
|
289 #endif
|
c@287
|
290 }
|
c@287
|
291
|
c@287
|
292 Thread::~Thread()
|
c@287
|
293 {
|
c@287
|
294 #ifdef DEBUG_THREAD
|
c@287
|
295 cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
|
c@287
|
296 #endif
|
c@287
|
297 if (m_extant) {
|
c@287
|
298 pthread_join(m_id, 0);
|
c@287
|
299 }
|
c@287
|
300 #ifdef DEBUG_THREAD
|
c@287
|
301 cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
|
c@287
|
302 #endif
|
c@287
|
303 }
|
c@287
|
304
|
c@287
|
305 void
|
c@287
|
306 Thread::start()
|
c@287
|
307 {
|
c@287
|
308 if (pthread_create(&m_id, 0, staticRun, this)) {
|
c@287
|
309 cerr << "ERROR: thread creation failed" << endl;
|
c@287
|
310 exit(1);
|
c@287
|
311 } else {
|
c@287
|
312 #ifdef DEBUG_THREAD
|
c@287
|
313 cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
|
c@287
|
314 #endif
|
c@287
|
315 m_extant = true;
|
c@287
|
316 }
|
c@287
|
317 }
|
c@287
|
318
|
c@287
|
319 void
|
c@287
|
320 Thread::wait()
|
c@287
|
321 {
|
c@287
|
322 if (m_extant) {
|
c@287
|
323 #ifdef DEBUG_THREAD
|
c@287
|
324 cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
325 #endif
|
c@287
|
326 pthread_join(m_id, 0);
|
c@287
|
327 #ifdef DEBUG_THREAD
|
c@287
|
328 cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
329 #endif
|
c@287
|
330 m_extant = false;
|
c@287
|
331 }
|
c@287
|
332 }
|
c@287
|
333
|
c@287
|
334 Thread::Id
|
c@287
|
335 Thread::id()
|
c@287
|
336 {
|
c@287
|
337 return m_id;
|
c@287
|
338 }
|
c@287
|
339
|
c@287
|
340 bool
|
c@287
|
341 Thread::threadingAvailable()
|
c@287
|
342 {
|
c@287
|
343 return true;
|
c@287
|
344 }
|
c@287
|
345
|
c@287
|
346 void *
|
c@287
|
347 Thread::staticRun(void *arg)
|
c@287
|
348 {
|
c@287
|
349 Thread *thread = static_cast<Thread *>(arg);
|
c@287
|
350 #ifdef DEBUG_THREAD
|
c@287
|
351 cerr << "THREAD DEBUG: " << (void *)pthread_self() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
|
c@287
|
352 #endif
|
c@287
|
353 thread->run();
|
c@287
|
354 return 0;
|
c@287
|
355 }
|
c@287
|
356
|
c@287
|
357 Mutex::Mutex()
|
c@287
|
358 #ifndef NO_THREAD_CHECKS
|
c@287
|
359 :
|
c@287
|
360 m_lockedBy(0),
|
c@287
|
361 m_locked(false)
|
c@287
|
362 #endif
|
c@287
|
363 {
|
c@287
|
364 pthread_mutex_init(&m_mutex, 0);
|
c@287
|
365 #ifdef DEBUG_MUTEX
|
c@287
|
366 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl;
|
c@287
|
367 #endif
|
c@287
|
368 }
|
c@287
|
369
|
c@287
|
370 Mutex::~Mutex()
|
c@287
|
371 {
|
c@287
|
372 #ifdef DEBUG_MUTEX
|
c@287
|
373 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl;
|
c@287
|
374 #endif
|
c@287
|
375 pthread_mutex_destroy(&m_mutex);
|
c@287
|
376 }
|
c@287
|
377
|
c@287
|
378 void
|
c@287
|
379 Mutex::lock()
|
c@287
|
380 {
|
c@287
|
381 #ifndef NO_THREAD_CHECKS
|
c@287
|
382 pthread_t tid = pthread_self();
|
c@287
|
383 if (m_locked && m_lockedBy == tid) {
|
c@287
|
384 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
|
c@287
|
385 }
|
c@287
|
386 #endif
|
c@287
|
387 #ifdef DEBUG_MUTEX
|
c@287
|
388 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
|
c@287
|
389 #endif
|
c@287
|
390 pthread_mutex_lock(&m_mutex);
|
c@287
|
391 #ifndef NO_THREAD_CHECKS
|
c@287
|
392 m_lockedBy = tid;
|
c@287
|
393 m_locked = true;
|
c@287
|
394 #endif
|
c@287
|
395 #ifdef DEBUG_MUTEX
|
c@287
|
396 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
|
c@287
|
397 #endif
|
c@287
|
398 }
|
c@287
|
399
|
c@287
|
400 void
|
c@287
|
401 Mutex::unlock()
|
c@287
|
402 {
|
c@287
|
403 #ifndef NO_THREAD_CHECKS
|
c@287
|
404 pthread_t tid = pthread_self();
|
c@287
|
405 if (!m_locked) {
|
c@287
|
406 cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl;
|
c@287
|
407 return;
|
c@287
|
408 } else if (m_lockedBy != tid) {
|
c@287
|
409 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
|
c@287
|
410 return;
|
c@287
|
411 }
|
c@287
|
412 #endif
|
c@287
|
413 #ifdef DEBUG_MUTEX
|
c@287
|
414 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
|
c@287
|
415 #endif
|
c@287
|
416 #ifndef NO_THREAD_CHECKS
|
c@287
|
417 m_locked = false;
|
c@287
|
418 #endif
|
c@287
|
419 pthread_mutex_unlock(&m_mutex);
|
c@287
|
420 }
|
c@287
|
421
|
c@287
|
422 bool
|
c@287
|
423 Mutex::trylock()
|
c@287
|
424 {
|
c@287
|
425 #ifndef NO_THREAD_CHECKS
|
c@287
|
426 pthread_t tid = pthread_self();
|
c@287
|
427 #endif
|
c@287
|
428 if (pthread_mutex_trylock(&m_mutex)) {
|
c@287
|
429 #ifdef DEBUG_MUTEX
|
c@287
|
430 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
|
c@287
|
431 #endif
|
c@287
|
432 return false;
|
c@287
|
433 } else {
|
c@287
|
434 #ifndef NO_THREAD_CHECKS
|
c@287
|
435 m_lockedBy = tid;
|
c@287
|
436 m_locked = true;
|
c@287
|
437 #endif
|
c@287
|
438 #ifdef DEBUG_MUTEX
|
c@287
|
439 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
|
c@287
|
440 #endif
|
c@287
|
441 return true;
|
c@287
|
442 }
|
c@287
|
443 }
|
c@287
|
444
|
c@287
|
445 Condition::Condition(string name) :
|
c@287
|
446 m_locked(false)
|
c@287
|
447 #ifdef DEBUG_CONDITION
|
c@287
|
448 , m_name(name)
|
c@287
|
449 #endif
|
c@287
|
450 {
|
c@287
|
451 pthread_mutex_init(&m_mutex, 0);
|
c@287
|
452 pthread_cond_init(&m_condition, 0);
|
c@287
|
453 #ifdef DEBUG_CONDITION
|
c@287
|
454 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Initialised condition " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
455 #endif
|
c@287
|
456 }
|
c@287
|
457
|
c@287
|
458 Condition::~Condition()
|
c@287
|
459 {
|
c@287
|
460 #ifdef DEBUG_CONDITION
|
c@287
|
461 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Destroying condition " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
462 #endif
|
c@287
|
463 if (m_locked) pthread_mutex_unlock(&m_mutex);
|
c@287
|
464 pthread_cond_destroy(&m_condition);
|
c@287
|
465 pthread_mutex_destroy(&m_mutex);
|
c@287
|
466 }
|
c@287
|
467
|
c@287
|
468 void
|
c@287
|
469 Condition::lock()
|
c@287
|
470 {
|
c@287
|
471 if (m_locked) {
|
c@287
|
472 #ifdef DEBUG_CONDITION
|
c@287
|
473 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Already locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
474 #endif
|
c@287
|
475 return;
|
c@287
|
476 }
|
c@287
|
477 #ifdef DEBUG_CONDITION
|
c@287
|
478 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
479 #endif
|
c@287
|
480 pthread_mutex_lock(&m_mutex);
|
c@287
|
481 m_locked = true;
|
c@287
|
482 #ifdef DEBUG_CONDITION
|
c@287
|
483 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
484 #endif
|
c@287
|
485 }
|
c@287
|
486
|
c@287
|
487 void
|
c@287
|
488 Condition::unlock()
|
c@287
|
489 {
|
c@287
|
490 if (!m_locked) {
|
c@287
|
491 #ifdef DEBUG_CONDITION
|
c@287
|
492 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
493 #endif
|
c@287
|
494 return;
|
c@287
|
495 }
|
c@287
|
496 #ifdef DEBUG_CONDITION
|
c@287
|
497 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
498 #endif
|
c@287
|
499 m_locked = false;
|
c@287
|
500 pthread_mutex_unlock(&m_mutex);
|
c@287
|
501 }
|
c@287
|
502
|
c@287
|
503 void
|
c@287
|
504 Condition::wait(int us)
|
c@287
|
505 {
|
c@287
|
506 if (us == 0) {
|
c@287
|
507
|
c@287
|
508 #ifdef DEBUG_CONDITION
|
c@287
|
509 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
510 #endif
|
c@287
|
511 pthread_cond_wait(&m_condition, &m_mutex);
|
c@287
|
512
|
c@287
|
513 } else {
|
c@287
|
514
|
c@287
|
515 struct timeval now;
|
c@287
|
516 gettimeofday(&now, 0);
|
c@287
|
517
|
c@287
|
518 now.tv_usec += us;
|
c@287
|
519 while (now.tv_usec > 1000000) {
|
c@287
|
520 now.tv_usec -= 1000000;
|
c@287
|
521 ++now.tv_sec;
|
c@287
|
522 }
|
c@287
|
523
|
c@287
|
524 struct timespec timeout;
|
c@287
|
525 timeout.tv_sec = now.tv_sec;
|
c@287
|
526 timeout.tv_nsec = now.tv_usec * 1000;
|
c@287
|
527
|
c@287
|
528 #ifdef DEBUG_CONDITION
|
c@287
|
529 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
530 #endif
|
c@287
|
531 pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
|
c@287
|
532 }
|
c@287
|
533
|
c@287
|
534 #ifdef DEBUG_CONDITION
|
c@287
|
535 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
536 #endif
|
c@287
|
537 }
|
c@287
|
538
|
c@287
|
539 void
|
c@287
|
540 Condition::signal()
|
c@287
|
541 {
|
c@287
|
542 #ifdef DEBUG_CONDITION
|
c@287
|
543 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
544 #endif
|
c@287
|
545 pthread_cond_signal(&m_condition);
|
c@287
|
546 }
|
c@287
|
547
|
c@287
|
548 #else /* !USE_PTHREADS */
|
c@287
|
549
|
c@287
|
550 Thread::Thread()
|
c@287
|
551 {
|
c@287
|
552 }
|
c@287
|
553
|
c@287
|
554 Thread::~Thread()
|
c@287
|
555 {
|
c@287
|
556 }
|
c@287
|
557
|
c@287
|
558 void
|
c@287
|
559 Thread::start()
|
c@287
|
560 {
|
c@287
|
561 abort();
|
c@287
|
562 }
|
c@287
|
563
|
c@287
|
564 void
|
c@287
|
565 Thread::wait()
|
c@287
|
566 {
|
c@287
|
567 abort();
|
c@287
|
568 }
|
c@287
|
569
|
c@287
|
570 Thread::Id
|
c@287
|
571 Thread::id()
|
c@287
|
572 {
|
c@287
|
573 abort();
|
c@287
|
574 }
|
c@287
|
575
|
c@287
|
576 bool
|
c@287
|
577 Thread::threadingAvailable()
|
c@287
|
578 {
|
c@287
|
579 return false;
|
c@287
|
580 }
|
c@287
|
581
|
c@287
|
582 Mutex::Mutex()
|
c@287
|
583 {
|
c@287
|
584 }
|
c@287
|
585
|
c@287
|
586 Mutex::~Mutex()
|
c@287
|
587 {
|
c@287
|
588 }
|
c@287
|
589
|
c@287
|
590 void
|
c@287
|
591 Mutex::lock()
|
c@287
|
592 {
|
c@287
|
593 abort();
|
c@287
|
594 }
|
c@287
|
595
|
c@287
|
596 void
|
c@287
|
597 Mutex::unlock()
|
c@287
|
598 {
|
c@287
|
599 abort();
|
c@287
|
600 }
|
c@287
|
601
|
c@287
|
602 bool
|
c@287
|
603 Mutex::trylock()
|
c@287
|
604 {
|
c@287
|
605 abort();
|
c@287
|
606 }
|
c@287
|
607
|
c@287
|
608 Condition::Condition(const char *)
|
c@287
|
609 {
|
c@287
|
610 }
|
c@287
|
611
|
c@287
|
612 Condition::~Condition()
|
c@287
|
613 {
|
c@287
|
614 }
|
c@287
|
615
|
c@287
|
616 void
|
c@287
|
617 Condition::lock()
|
c@287
|
618 {
|
c@287
|
619 abort();
|
c@287
|
620 }
|
c@287
|
621
|
c@287
|
622 void
|
c@287
|
623 Condition::wait(int us)
|
c@287
|
624 {
|
c@287
|
625 abort();
|
c@287
|
626 }
|
c@287
|
627
|
c@287
|
628 void
|
c@287
|
629 Condition::signal()
|
c@287
|
630 {
|
c@287
|
631 abort();
|
c@287
|
632 }
|
c@287
|
633
|
c@287
|
634 #endif /* !USE_PTHREADS */
|
c@287
|
635 #endif /* !_WIN32 */
|
c@287
|
636
|
c@287
|
637 MutexLocker::MutexLocker(Mutex *mutex) :
|
c@287
|
638 m_mutex(mutex)
|
c@287
|
639 {
|
c@287
|
640 if (m_mutex) {
|
c@287
|
641 m_mutex->lock();
|
c@287
|
642 }
|
c@287
|
643 }
|
c@287
|
644
|
c@287
|
645 MutexLocker::~MutexLocker()
|
c@287
|
646 {
|
c@287
|
647 if (m_mutex) {
|
c@287
|
648 m_mutex->unlock();
|
c@287
|
649 }
|
c@287
|
650 }
|
c@287
|
651
|