annotate thread/Thread.cpp @ 209:ccd2019190bf msvc

Some MSVC fixes, including (temporarily, probably) renaming the FFT source file to avoid getting it mixed up with the Vamp SDK one in our object dir
author Chris Cannam
date Thu, 01 Feb 2018 16:34:08 +0000
parents e4a57215ddee
children
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
Chris@189 441 Condition::Condition(string
Chris@189 442 #ifdef DEBUG_CONDITION
Chris@189 443 name
Chris@189 444 #endif
Chris@189 445 ) :
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 #ifdef DEBUG_CONDITION
cannam@62 472 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
cannam@62 473 #endif
cannam@62 474 pthread_mutex_lock(&m_mutex);
cannam@62 475 m_locked = true;
cannam@62 476 #ifdef DEBUG_CONDITION
cannam@62 477 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Locked " << &m_condition << " \"" << m_name << "\"" << endl;
cannam@62 478 #endif
cannam@62 479 }
cannam@62 480
cannam@62 481 void
cannam@62 482 Condition::unlock()
cannam@62 483 {
cannam@62 484 if (!m_locked) {
cannam@62 485 #ifdef DEBUG_CONDITION
cannam@62 486 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Not locked " << &m_condition << " \"" << m_name << "\"" << endl;
cannam@62 487 #endif
cannam@62 488 return;
cannam@62 489 }
cannam@62 490 #ifdef DEBUG_CONDITION
cannam@62 491 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Unlocking " << &m_condition << " \"" << m_name << "\"" << endl;
cannam@62 492 #endif
cannam@62 493 m_locked = false;
cannam@62 494 pthread_mutex_unlock(&m_mutex);
cannam@62 495 }
cannam@62 496
cannam@62 497 void
cannam@62 498 Condition::wait(int us)
cannam@62 499 {
cannam@62 500 if (us == 0) {
cannam@62 501
cannam@62 502 #ifdef DEBUG_CONDITION
cannam@62 503 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
cannam@62 504 #endif
cannam@62 505 pthread_cond_wait(&m_condition, &m_mutex);
cannam@62 506
cannam@62 507 } else {
cannam@62 508
cannam@62 509 struct timeval now;
cannam@62 510 gettimeofday(&now, 0);
cannam@62 511
cannam@62 512 now.tv_usec += us;
cannam@62 513 while (now.tv_usec > 1000000) {
cannam@62 514 now.tv_usec -= 1000000;
cannam@62 515 ++now.tv_sec;
cannam@62 516 }
cannam@62 517
cannam@62 518 struct timespec timeout;
cannam@62 519 timeout.tv_sec = now.tv_sec;
cannam@62 520 timeout.tv_nsec = now.tv_usec * 1000;
cannam@62 521
cannam@62 522 #ifdef DEBUG_CONDITION
cannam@62 523 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Timed waiting on " << &m_condition << " \"" << m_name << "\"" << endl;
cannam@62 524 #endif
cannam@62 525 pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
cannam@62 526 }
cannam@62 527
cannam@62 528 #ifdef DEBUG_CONDITION
cannam@62 529 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
cannam@62 530 #endif
cannam@69 531
cannam@69 532 m_locked = true;
cannam@62 533 }
cannam@62 534
cannam@62 535 void
cannam@62 536 Condition::signal()
cannam@62 537 {
cannam@62 538 #ifdef DEBUG_CONDITION
cannam@62 539 cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Signalling " << &m_condition << " \"" << m_name << "\"" << endl;
cannam@62 540 #endif
cannam@62 541 pthread_cond_signal(&m_condition);
cannam@62 542 }
cannam@62 543
cannam@62 544 #else /* !USE_PTHREADS */
cannam@62 545
cannam@62 546 Thread::Thread()
cannam@62 547 {
cannam@62 548 }
cannam@62 549
cannam@62 550 Thread::~Thread()
cannam@62 551 {
cannam@62 552 }
cannam@62 553
cannam@62 554 void
cannam@62 555 Thread::start()
cannam@62 556 {
cannam@62 557 abort();
cannam@62 558 }
cannam@62 559
cannam@62 560 void
cannam@62 561 Thread::wait()
cannam@62 562 {
cannam@62 563 abort();
cannam@62 564 }
cannam@62 565
cannam@62 566 Thread::Id
cannam@62 567 Thread::id()
cannam@62 568 {
cannam@62 569 abort();
cannam@62 570 }
cannam@62 571
cannam@62 572 bool
cannam@62 573 Thread::threadingAvailable()
cannam@62 574 {
cannam@62 575 return false;
cannam@62 576 }
cannam@62 577
cannam@62 578 Mutex::Mutex()
cannam@62 579 {
cannam@62 580 }
cannam@62 581
cannam@62 582 Mutex::~Mutex()
cannam@62 583 {
cannam@62 584 }
cannam@62 585
cannam@62 586 void
cannam@62 587 Mutex::lock()
cannam@62 588 {
cannam@62 589 abort();
cannam@62 590 }
cannam@62 591
cannam@62 592 void
cannam@62 593 Mutex::unlock()
cannam@62 594 {
cannam@62 595 abort();
cannam@62 596 }
cannam@62 597
cannam@62 598 bool
cannam@62 599 Mutex::trylock()
cannam@62 600 {
cannam@62 601 abort();
cannam@62 602 }
cannam@62 603
cannam@62 604 Condition::Condition(const char *)
cannam@62 605 {
cannam@62 606 }
cannam@62 607
cannam@62 608 Condition::~Condition()
cannam@62 609 {
cannam@62 610 }
cannam@62 611
cannam@62 612 void
cannam@62 613 Condition::lock()
cannam@62 614 {
cannam@62 615 abort();
cannam@62 616 }
cannam@62 617
cannam@62 618 void
cannam@62 619 Condition::wait(int us)
cannam@62 620 {
cannam@62 621 abort();
cannam@62 622 }
cannam@62 623
cannam@62 624 void
cannam@62 625 Condition::signal()
cannam@62 626 {
cannam@62 627 abort();
cannam@62 628 }
cannam@62 629
cannam@62 630 #endif /* !USE_PTHREADS */
cannam@62 631 #endif /* !_WIN32 */
cannam@62 632
cannam@62 633 MutexLocker::MutexLocker(Mutex *mutex) :
cannam@62 634 m_mutex(mutex)
cannam@62 635 {
cannam@62 636 if (m_mutex) {
cannam@62 637 m_mutex->lock();
cannam@62 638 }
cannam@62 639 }
cannam@62 640
cannam@62 641 MutexLocker::~MutexLocker()
cannam@62 642 {
cannam@62 643 if (m_mutex) {
cannam@62 644 m_mutex->unlock();
cannam@62 645 }
cannam@62 646 }
cannam@62 647