annotate thread/Thread.cpp @ 116:fac40444b8c3 pvoc

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