annotate thread/Thread.cpp @ 62:b63f1ccbc9b6

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