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 #ifdef DEBUG_CONDITION
|
c@287
|
211 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
212 #endif
|
c@287
|
213 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
214 m_locked = true;
|
c@287
|
215 #ifdef DEBUG_CONDITION
|
c@287
|
216 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
217 #endif
|
c@287
|
218 }
|
c@287
|
219
|
c@287
|
220 void
|
c@287
|
221 Condition::unlock()
|
c@287
|
222 {
|
c@287
|
223 if (!m_locked) {
|
c@287
|
224 #ifdef DEBUG_CONDITION
|
c@287
|
225 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
226 #endif
|
c@287
|
227 return;
|
c@287
|
228 }
|
c@287
|
229 #ifdef DEBUG_CONDITION
|
c@287
|
230 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
231 #endif
|
c@287
|
232 m_locked = false;
|
c@287
|
233 ReleaseMutex(m_mutex);
|
c@287
|
234 }
|
c@287
|
235
|
c@287
|
236 void
|
c@287
|
237 Condition::wait(int us)
|
c@287
|
238 {
|
c@287
|
239 if (us == 0) {
|
c@287
|
240
|
c@287
|
241 #ifdef DEBUG_CONDITION
|
c@287
|
242 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
243 #endif
|
c@287
|
244 SignalObjectAndWait(m_mutex, m_condition, INFINITE, FALSE);
|
c@287
|
245 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
246
|
c@287
|
247 } else {
|
c@287
|
248
|
c@287
|
249 DWORD ms = us / 1000;
|
c@287
|
250 if (us > 0 && ms == 0) ms = 1;
|
c@287
|
251
|
c@287
|
252 #ifdef DEBUG_CONDITION
|
c@287
|
253 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
254 #endif
|
c@287
|
255 SignalObjectAndWait(m_mutex, m_condition, ms, FALSE);
|
c@287
|
256 WaitForSingleObject(m_mutex, INFINITE);
|
c@287
|
257 }
|
c@287
|
258
|
c@287
|
259 #ifdef DEBUG_CONDITION
|
c@287
|
260 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
261 #endif
|
c@296
|
262
|
c@296
|
263 m_locked = true;
|
c@287
|
264 }
|
c@287
|
265
|
c@287
|
266 void
|
c@287
|
267 Condition::signal()
|
c@287
|
268 {
|
c@287
|
269 #ifdef DEBUG_CONDITION
|
c@287
|
270 cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
271 #endif
|
c@287
|
272 SetEvent(m_condition);
|
c@287
|
273 }
|
c@287
|
274
|
c@287
|
275 #else /* !_WIN32 */
|
c@287
|
276
|
c@287
|
277 #ifdef USE_PTHREADS
|
c@287
|
278
|
c@287
|
279 Thread::Thread() :
|
c@287
|
280 m_id(0),
|
c@287
|
281 m_extant(false)
|
c@287
|
282 {
|
c@287
|
283 #ifdef DEBUG_THREAD
|
c@287
|
284 cerr << "THREAD DEBUG: Created thread object " << this << endl;
|
c@287
|
285 #endif
|
c@287
|
286 }
|
c@287
|
287
|
c@287
|
288 Thread::~Thread()
|
c@287
|
289 {
|
c@287
|
290 #ifdef DEBUG_THREAD
|
c@287
|
291 cerr << "THREAD DEBUG: Destroying thread object " << this << ", id " << m_id << endl;
|
c@287
|
292 #endif
|
c@287
|
293 if (m_extant) {
|
c@287
|
294 pthread_join(m_id, 0);
|
c@287
|
295 }
|
c@287
|
296 #ifdef DEBUG_THREAD
|
c@287
|
297 cerr << "THREAD DEBUG: Destroyed thread object " << this << endl;
|
c@287
|
298 #endif
|
c@287
|
299 }
|
c@287
|
300
|
c@287
|
301 void
|
c@287
|
302 Thread::start()
|
c@287
|
303 {
|
c@287
|
304 if (pthread_create(&m_id, 0, staticRun, this)) {
|
c@287
|
305 cerr << "ERROR: thread creation failed" << endl;
|
c@287
|
306 exit(1);
|
c@287
|
307 } else {
|
c@287
|
308 #ifdef DEBUG_THREAD
|
c@287
|
309 cerr << "THREAD DEBUG: Created thread " << m_id << " for thread object " << this << endl;
|
c@287
|
310 #endif
|
c@287
|
311 m_extant = true;
|
c@287
|
312 }
|
c@287
|
313 }
|
c@287
|
314
|
c@287
|
315 void
|
c@287
|
316 Thread::wait()
|
c@287
|
317 {
|
c@287
|
318 if (m_extant) {
|
c@287
|
319 #ifdef DEBUG_THREAD
|
c@287
|
320 cerr << "THREAD DEBUG: Waiting on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
321 #endif
|
c@287
|
322 pthread_join(m_id, 0);
|
c@287
|
323 #ifdef DEBUG_THREAD
|
c@287
|
324 cerr << "THREAD DEBUG: Waited on thread " << m_id << " for thread object " << this << endl;
|
c@287
|
325 #endif
|
c@287
|
326 m_extant = false;
|
c@287
|
327 }
|
c@287
|
328 }
|
c@287
|
329
|
c@287
|
330 Thread::Id
|
c@287
|
331 Thread::id()
|
c@287
|
332 {
|
c@287
|
333 return m_id;
|
c@287
|
334 }
|
c@287
|
335
|
c@287
|
336 bool
|
c@287
|
337 Thread::threadingAvailable()
|
c@287
|
338 {
|
c@287
|
339 return true;
|
c@287
|
340 }
|
c@287
|
341
|
c@287
|
342 void *
|
c@287
|
343 Thread::staticRun(void *arg)
|
c@287
|
344 {
|
c@287
|
345 Thread *thread = static_cast<Thread *>(arg);
|
c@287
|
346 #ifdef DEBUG_THREAD
|
c@287
|
347 cerr << "THREAD DEBUG: " << (void *)pthread_self() << ": Running thread " << thread->m_id << " for thread object " << thread << endl;
|
c@287
|
348 #endif
|
c@287
|
349 thread->run();
|
c@287
|
350 return 0;
|
c@287
|
351 }
|
c@287
|
352
|
c@287
|
353 Mutex::Mutex()
|
c@287
|
354 #ifndef NO_THREAD_CHECKS
|
c@287
|
355 :
|
c@287
|
356 m_lockedBy(0),
|
c@287
|
357 m_locked(false)
|
c@287
|
358 #endif
|
c@287
|
359 {
|
c@287
|
360 pthread_mutex_init(&m_mutex, 0);
|
c@287
|
361 #ifdef DEBUG_MUTEX
|
c@287
|
362 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Initialised mutex " << &m_mutex << endl;
|
c@287
|
363 #endif
|
c@287
|
364 }
|
c@287
|
365
|
c@287
|
366 Mutex::~Mutex()
|
c@287
|
367 {
|
c@287
|
368 #ifdef DEBUG_MUTEX
|
c@287
|
369 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Destroying mutex " << &m_mutex << endl;
|
c@287
|
370 #endif
|
c@287
|
371 pthread_mutex_destroy(&m_mutex);
|
c@287
|
372 }
|
c@287
|
373
|
c@287
|
374 void
|
c@287
|
375 Mutex::lock()
|
c@287
|
376 {
|
c@287
|
377 #ifndef NO_THREAD_CHECKS
|
c@287
|
378 pthread_t tid = pthread_self();
|
c@287
|
379 if (m_locked && m_lockedBy == tid) {
|
c@287
|
380 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl;
|
c@287
|
381 }
|
c@287
|
382 #endif
|
c@287
|
383 #ifdef DEBUG_MUTEX
|
c@287
|
384 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl;
|
c@287
|
385 #endif
|
c@287
|
386 pthread_mutex_lock(&m_mutex);
|
c@287
|
387 #ifndef NO_THREAD_CHECKS
|
c@287
|
388 m_lockedBy = tid;
|
c@287
|
389 m_locked = true;
|
c@287
|
390 #endif
|
c@287
|
391 #ifdef DEBUG_MUTEX
|
c@287
|
392 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl;
|
c@287
|
393 #endif
|
c@287
|
394 }
|
c@287
|
395
|
c@287
|
396 void
|
c@287
|
397 Mutex::unlock()
|
c@287
|
398 {
|
c@287
|
399 #ifndef NO_THREAD_CHECKS
|
c@287
|
400 pthread_t tid = pthread_self();
|
c@287
|
401 if (!m_locked) {
|
c@287
|
402 cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl;
|
c@287
|
403 return;
|
c@287
|
404 } else if (m_lockedBy != tid) {
|
c@287
|
405 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl;
|
c@287
|
406 return;
|
c@287
|
407 }
|
c@287
|
408 #endif
|
c@287
|
409 #ifdef DEBUG_MUTEX
|
c@287
|
410 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl;
|
c@287
|
411 #endif
|
c@287
|
412 #ifndef NO_THREAD_CHECKS
|
c@287
|
413 m_locked = false;
|
c@287
|
414 #endif
|
c@287
|
415 pthread_mutex_unlock(&m_mutex);
|
c@287
|
416 }
|
c@287
|
417
|
c@287
|
418 bool
|
c@287
|
419 Mutex::trylock()
|
c@287
|
420 {
|
c@287
|
421 #ifndef NO_THREAD_CHECKS
|
c@287
|
422 pthread_t tid = pthread_self();
|
c@287
|
423 #endif
|
c@287
|
424 if (pthread_mutex_trylock(&m_mutex)) {
|
c@287
|
425 #ifdef DEBUG_MUTEX
|
c@287
|
426 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl;
|
c@287
|
427 #endif
|
c@287
|
428 return false;
|
c@287
|
429 } else {
|
c@287
|
430 #ifndef NO_THREAD_CHECKS
|
c@287
|
431 m_lockedBy = tid;
|
c@287
|
432 m_locked = true;
|
c@287
|
433 #endif
|
c@287
|
434 #ifdef DEBUG_MUTEX
|
c@287
|
435 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl;
|
c@287
|
436 #endif
|
c@287
|
437 return true;
|
c@287
|
438 }
|
c@287
|
439 }
|
c@287
|
440
|
c@414
|
441 Condition::Condition(string
|
c@414
|
442 #ifdef DEBUG_CONDITION
|
c@414
|
443 name
|
c@414
|
444 #endif
|
c@414
|
445 ) :
|
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 #ifdef DEBUG_CONDITION
|
c@287
|
472 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
473 #endif
|
c@287
|
474 pthread_mutex_lock(&m_mutex);
|
c@287
|
475 m_locked = true;
|
c@287
|
476 #ifdef DEBUG_CONDITION
|
c@287
|
477 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
478 #endif
|
c@287
|
479 }
|
c@287
|
480
|
c@287
|
481 void
|
c@287
|
482 Condition::unlock()
|
c@287
|
483 {
|
c@287
|
484 if (!m_locked) {
|
c@287
|
485 #ifdef DEBUG_CONDITION
|
c@287
|
486 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
487 #endif
|
c@287
|
488 return;
|
c@287
|
489 }
|
c@287
|
490 #ifdef DEBUG_CONDITION
|
c@287
|
491 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
492 #endif
|
c@287
|
493 m_locked = false;
|
c@287
|
494 pthread_mutex_unlock(&m_mutex);
|
c@287
|
495 }
|
c@287
|
496
|
c@287
|
497 void
|
c@287
|
498 Condition::wait(int us)
|
c@287
|
499 {
|
c@287
|
500 if (us == 0) {
|
c@287
|
501
|
c@287
|
502 #ifdef DEBUG_CONDITION
|
c@287
|
503 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
504 #endif
|
c@287
|
505 pthread_cond_wait(&m_condition, &m_mutex);
|
c@287
|
506
|
c@287
|
507 } else {
|
c@287
|
508
|
c@287
|
509 struct timeval now;
|
c@287
|
510 gettimeofday(&now, 0);
|
c@287
|
511
|
c@287
|
512 now.tv_usec += us;
|
c@287
|
513 while (now.tv_usec > 1000000) {
|
c@287
|
514 now.tv_usec -= 1000000;
|
c@287
|
515 ++now.tv_sec;
|
c@287
|
516 }
|
c@287
|
517
|
c@287
|
518 struct timespec timeout;
|
c@287
|
519 timeout.tv_sec = now.tv_sec;
|
c@287
|
520 timeout.tv_nsec = now.tv_usec * 1000;
|
c@287
|
521
|
c@287
|
522 #ifdef DEBUG_CONDITION
|
c@287
|
523 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
524 #endif
|
c@287
|
525 pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
|
c@287
|
526 }
|
c@287
|
527
|
c@287
|
528 #ifdef DEBUG_CONDITION
|
c@287
|
529 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
530 #endif
|
c@294
|
531
|
c@294
|
532 m_locked = true;
|
c@287
|
533 }
|
c@287
|
534
|
c@287
|
535 void
|
c@287
|
536 Condition::signal()
|
c@287
|
537 {
|
c@287
|
538 #ifdef DEBUG_CONDITION
|
c@287
|
539 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
|
c@287
|
540 #endif
|
c@287
|
541 pthread_cond_signal(&m_condition);
|
c@287
|
542 }
|
c@287
|
543
|
c@287
|
544 #else /* !USE_PTHREADS */
|
c@287
|
545
|
c@287
|
546 Thread::Thread()
|
c@287
|
547 {
|
c@287
|
548 }
|
c@287
|
549
|
c@287
|
550 Thread::~Thread()
|
c@287
|
551 {
|
c@287
|
552 }
|
c@287
|
553
|
c@287
|
554 void
|
c@287
|
555 Thread::start()
|
c@287
|
556 {
|
c@287
|
557 abort();
|
c@287
|
558 }
|
c@287
|
559
|
c@287
|
560 void
|
c@287
|
561 Thread::wait()
|
c@287
|
562 {
|
c@287
|
563 abort();
|
c@287
|
564 }
|
c@287
|
565
|
c@287
|
566 Thread::Id
|
c@287
|
567 Thread::id()
|
c@287
|
568 {
|
c@287
|
569 abort();
|
c@287
|
570 }
|
c@287
|
571
|
c@287
|
572 bool
|
c@287
|
573 Thread::threadingAvailable()
|
c@287
|
574 {
|
c@287
|
575 return false;
|
c@287
|
576 }
|
c@287
|
577
|
c@287
|
578 Mutex::Mutex()
|
c@287
|
579 {
|
c@287
|
580 }
|
c@287
|
581
|
c@287
|
582 Mutex::~Mutex()
|
c@287
|
583 {
|
c@287
|
584 }
|
c@287
|
585
|
c@287
|
586 void
|
c@287
|
587 Mutex::lock()
|
c@287
|
588 {
|
c@287
|
589 abort();
|
c@287
|
590 }
|
c@287
|
591
|
c@287
|
592 void
|
c@287
|
593 Mutex::unlock()
|
c@287
|
594 {
|
c@287
|
595 abort();
|
c@287
|
596 }
|
c@287
|
597
|
c@287
|
598 bool
|
c@287
|
599 Mutex::trylock()
|
c@287
|
600 {
|
c@287
|
601 abort();
|
c@287
|
602 }
|
c@287
|
603
|
c@287
|
604 Condition::Condition(const char *)
|
c@287
|
605 {
|
c@287
|
606 }
|
c@287
|
607
|
c@287
|
608 Condition::~Condition()
|
c@287
|
609 {
|
c@287
|
610 }
|
c@287
|
611
|
c@287
|
612 void
|
c@287
|
613 Condition::lock()
|
c@287
|
614 {
|
c@287
|
615 abort();
|
c@287
|
616 }
|
c@287
|
617
|
c@287
|
618 void
|
c@287
|
619 Condition::wait(int us)
|
c@287
|
620 {
|
c@287
|
621 abort();
|
c@287
|
622 }
|
c@287
|
623
|
c@287
|
624 void
|
c@287
|
625 Condition::signal()
|
c@287
|
626 {
|
c@287
|
627 abort();
|
c@287
|
628 }
|
c@287
|
629
|
c@287
|
630 #endif /* !USE_PTHREADS */
|
c@287
|
631 #endif /* !_WIN32 */
|
c@287
|
632
|
c@287
|
633 MutexLocker::MutexLocker(Mutex *mutex) :
|
c@287
|
634 m_mutex(mutex)
|
c@287
|
635 {
|
c@287
|
636 if (m_mutex) {
|
c@287
|
637 m_mutex->lock();
|
c@287
|
638 }
|
c@287
|
639 }
|
c@287
|
640
|
c@287
|
641 MutexLocker::~MutexLocker()
|
c@287
|
642 {
|
c@287
|
643 if (m_mutex) {
|
c@287
|
644 m_mutex->unlock();
|
c@287
|
645 }
|
c@287
|
646 }
|
c@287
|
647
|