3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* Copyright (C) 2005 - 2015 Christian Schoenebeck * |
* Copyright (C) 2005 - 2017 Christian Schoenebeck * |
7 |
* * |
* * |
8 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
9 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
246 |
// *************** Condition *************** |
// *************** Condition *************** |
247 |
// * |
// * |
248 |
|
|
249 |
Condition::Condition(bool bInitialCondition) { |
Condition::Condition(bool bInitialCondition, Mutex::type_t mutexType) |
250 |
|
: Mutex(mutexType) |
251 |
|
{ |
252 |
dmsg(7,("Condition:: constructor, bInitialCondition=%d\n", bInitialCondition)); |
dmsg(7,("Condition:: constructor, bInitialCondition=%d\n", bInitialCondition)); |
253 |
#if defined(WIN32) |
#if defined(WIN32) |
254 |
ConditionInternal::win32thread_cond_init(&__win32_true_condition, NULL); |
ConditionInternal::win32thread_cond_init(&__win32_true_condition, NULL); |
281 |
} |
} |
282 |
#endif |
#endif |
283 |
|
|
284 |
int Condition::WaitIf(bool bCondition, long TimeoutSeconds, long TimeoutNanoSeconds) { |
int Condition::WaitIfInternal(bool bLock, bool bCondition, long TimeoutSeconds, long TimeoutNanoSeconds) { |
285 |
dmsg(7,("Condition::WaitIf: bCondition=%d TimeoutSeconds=%ld TimeoutNanoSeconds=%ld\n",bCondition, TimeoutSeconds, TimeoutNanoSeconds)); |
dmsg(7,("Condition::WaitIfInternal: bCondition=%d TimeoutSeconds=%ld TimeoutNanoSeconds=%ld\n",bCondition, TimeoutSeconds, TimeoutNanoSeconds)); |
286 |
dmsg(7,("Condition::Waitif() -> LOCK()\n")); |
if (bLock) { |
287 |
Lock(); |
dmsg(7,("Condition::WaitIfInternal() -> LOCK()\n")); |
288 |
dmsg(7,("Condition::Waitif() -> LOCK() passed\n")); |
Lock(); |
289 |
|
dmsg(7,("Condition::WaitIfInternal() -> LOCK() passed\n")); |
290 |
|
} |
291 |
int res = 0; |
int res = 0; |
292 |
#ifndef WIN32 |
#ifndef WIN32 |
293 |
pthread_cleanup_push(condition_cleanup, this); |
pthread_cleanup_push(condition_cleanup, this); |
298 |
win32_timespec timeout; |
win32_timespec timeout; |
299 |
timeout.tv_sec = TimeoutSeconds; |
timeout.tv_sec = TimeoutSeconds; |
300 |
timeout.tv_nsec = TimeoutNanoSeconds; |
timeout.tv_nsec = TimeoutNanoSeconds; |
301 |
dmsg(7,("Condition::Waitif() -> waiting for 'false' condition with timeout\n")); |
dmsg(7,("Condition::WaitIfInternal() -> waiting for 'false' condition with timeout\n")); |
302 |
res = ConditionInternal::win32thread_cond_timedwait(&__win32_false_condition, &hMutex, &timeout); |
res = ConditionInternal::win32thread_cond_timedwait(&__win32_false_condition, &hMutex, &timeout); |
303 |
dmsg(7,("Condition::Waitif() -> awakened from 'false' condition waiting\n")); |
dmsg(7,("Condition::WaitIfInternal() -> awakened from 'false' condition waiting\n")); |
304 |
#else |
#else |
305 |
if (TimeoutSeconds || TimeoutNanoSeconds) { // wait with timeout |
if (TimeoutSeconds || TimeoutNanoSeconds) { // wait with timeout |
306 |
struct timeval now; |
struct timeval now; |
308 |
timespec timeout; |
timespec timeout; |
309 |
timeout.tv_sec = now.tv_sec + TimeoutSeconds; |
timeout.tv_sec = now.tv_sec + TimeoutSeconds; |
310 |
timeout.tv_nsec = now.tv_usec * 1000 + TimeoutNanoSeconds; |
timeout.tv_nsec = now.tv_usec * 1000 + TimeoutNanoSeconds; |
311 |
dmsg(7,("Condition::Waitif() -> waiting for 'false' condition with timeout\n")); |
dmsg(7,("Condition::WaitIfInternal() -> waiting for 'false' condition with timeout\n")); |
312 |
res = pthread_cond_timedwait(&__posix_false_condition, &__posix_mutex, &timeout); |
res = pthread_cond_timedwait(&__posix_false_condition, &__posix_mutex, &timeout); |
313 |
dmsg(7,("Condition::Waitif() -> awakened from 'false' condition waiting\n")); |
dmsg(7,("Condition::WaitIfInternal() -> awakened from 'false' condition waiting\n")); |
314 |
} |
} |
315 |
else { // wait without timeout |
else { // wait without timeout |
316 |
dmsg(7,("Condition::Waitif() -> waiting for 'false' condition\n")); |
dmsg(7,("Condition::WaitIfInternal() -> waiting for 'false' condition\n")); |
317 |
pthread_cond_wait(&__posix_false_condition, &__posix_mutex); |
pthread_cond_wait(&__posix_false_condition, &__posix_mutex); |
318 |
dmsg(7,("Condition::Waitif() -> awakened from 'false' condition waiting\n")); |
dmsg(7,("Condition::WaitIfInternal() -> awakened from 'false' condition waiting\n")); |
319 |
} |
} |
320 |
#endif |
#endif |
321 |
} |
} |
324 |
win32_timespec timeout; |
win32_timespec timeout; |
325 |
timeout.tv_sec = TimeoutSeconds; |
timeout.tv_sec = TimeoutSeconds; |
326 |
timeout.tv_nsec = TimeoutNanoSeconds; |
timeout.tv_nsec = TimeoutNanoSeconds; |
327 |
dmsg(7,("Condition::Waitif() -> waiting for 'true' condition with timeout\n")); |
dmsg(7,("Condition::WaitIfInternal() -> waiting for 'true' condition with timeout\n")); |
328 |
res = ConditionInternal::win32thread_cond_timedwait(&__win32_true_condition, &hMutex, &timeout); |
res = ConditionInternal::win32thread_cond_timedwait(&__win32_true_condition, &hMutex, &timeout); |
329 |
dmsg(7,("Condition::Waitif() -> awakened from 'true' condition waiting\n")); |
dmsg(7,("Condition::WaitIfInternal() -> awakened from 'true' condition waiting\n")); |
330 |
#else |
#else |
331 |
if (TimeoutSeconds || TimeoutNanoSeconds) { // wait with timeout |
if (TimeoutSeconds || TimeoutNanoSeconds) { // wait with timeout |
332 |
struct timeval now; |
struct timeval now; |
334 |
timespec timeout; |
timespec timeout; |
335 |
timeout.tv_sec = now.tv_sec + TimeoutSeconds; |
timeout.tv_sec = now.tv_sec + TimeoutSeconds; |
336 |
timeout.tv_nsec = now.tv_usec * 1000 + TimeoutNanoSeconds; |
timeout.tv_nsec = now.tv_usec * 1000 + TimeoutNanoSeconds; |
337 |
dmsg(7,("Condition::Waitif() -> waiting for 'true' condition with timeout\n")); |
dmsg(7,("Condition::WaitIfInternal() -> waiting for 'true' condition with timeout\n")); |
338 |
res = pthread_cond_timedwait(&__posix_true_condition, &__posix_mutex, &timeout); |
res = pthread_cond_timedwait(&__posix_true_condition, &__posix_mutex, &timeout); |
339 |
dmsg(7,("Condition::Waitif() -> awakened from 'true' condition waiting\n")); |
dmsg(7,("Condition::WaitIfInternal() -> awakened from 'true' condition waiting\n")); |
340 |
} |
} |
341 |
else { // wait without timeout |
else { // wait without timeout |
342 |
dmsg(7,("Condition::Waitif() -> waiting for 'true' condition\n")); |
dmsg(7,("Condition::WaitIfInternal() -> waiting for 'true' condition\n")); |
343 |
pthread_cond_wait(&__posix_true_condition, &__posix_mutex); |
pthread_cond_wait(&__posix_true_condition, &__posix_mutex); |
344 |
dmsg(7,("Condition::Waitif() -> awakened from 'true' condition waiting\n")); |
dmsg(7,("Condition::WaitIfInternal() -> awakened from 'true' condition waiting\n")); |
345 |
} |
} |
346 |
#endif |
#endif |
347 |
} |
} |
352 |
return res; |
return res; |
353 |
} |
} |
354 |
|
|
355 |
|
int Condition::WaitIf(bool bCondition, long TimeoutSeconds, long TimeoutNanoSeconds) { |
356 |
|
return WaitIfInternal(true/*do lock*/, bCondition, TimeoutSeconds, TimeoutNanoSeconds); |
357 |
|
} |
358 |
|
|
359 |
|
int Condition::PreLockedWaitIf(bool bCondition, long TimeoutSeconds, long TimeoutNanoSeconds) { |
360 |
|
return WaitIfInternal(false/*don't lock*/, bCondition, TimeoutSeconds, TimeoutNanoSeconds); |
361 |
|
} |
362 |
|
|
363 |
int Condition::WaitAndUnlockIf(bool bCondition, long TimeoutSeconds, long TimeoutNanoSeconds) { |
int Condition::WaitAndUnlockIf(bool bCondition, long TimeoutSeconds, long TimeoutNanoSeconds) { |
364 |
int res = WaitIf(bCondition, TimeoutSeconds, TimeoutNanoSeconds); |
int res = WaitIfInternal(true/*do lock*/, bCondition, TimeoutSeconds, TimeoutNanoSeconds); |
365 |
dmsg(7,("Condition::WaitAndUnlockIf() -> UNLOCK()\n")); |
dmsg(7,("Condition::WaitAndUnlockIf() -> UNLOCK()\n")); |
366 |
Unlock(); |
Unlock(); |
367 |
dmsg(7,("Condition::WaitAndUnlockIf() -> UNLOCK() passed\n")); |
dmsg(7,("Condition::WaitAndUnlockIf() -> UNLOCK() passed\n")); |
368 |
return res; |
return res; |
369 |
} |
} |
370 |
|
|
371 |
void Condition::Set(bool bCondition) { |
int Condition::PreLockedWaitAndUnlockIf(bool bCondition, long TimeoutSeconds, long TimeoutNanoSeconds) { |
372 |
|
int res = WaitIfInternal(false/*don't lock*/, bCondition, TimeoutSeconds, TimeoutNanoSeconds); |
373 |
|
dmsg(7,("Condition::PreLockedWaitAndUnlockIf() -> UNLOCK()\n")); |
374 |
|
Unlock(); |
375 |
|
dmsg(7,("Condition::PreLockedWaitAndUnlockIf() -> UNLOCK() passed\n")); |
376 |
|
return res; |
377 |
|
} |
378 |
|
|
379 |
|
void Condition::SetInternal(bool bLock, bool bCondition) { |
380 |
dmsg(7,("Condition::Set() -> LOCK()\n")); |
dmsg(7,("Condition::Set() -> LOCK()\n")); |
381 |
LockGuard lock(*this); |
LockGuard lock = (bLock) ? LockGuard(*this) : LockGuard(); |
382 |
dmsg(7,("Condition::Set() -> LOCK() passed\n")); |
dmsg(7,("Condition::Set() -> LOCK() passed\n")); |
383 |
if (this->bCondition != bCondition) { |
if (this->bCondition != bCondition) { |
384 |
this->bCondition = bCondition; |
this->bCondition = bCondition; |
401 |
} |
} |
402 |
} |
} |
403 |
|
|
404 |
|
void Condition::Set(bool bCondition) { |
405 |
|
SetInternal(true/*do lock*/, bCondition); |
406 |
|
} |
407 |
|
|
408 |
|
void Condition::PreLockedSet(bool bCondition) { |
409 |
|
SetInternal(false/*don't lock*/, bCondition); |
410 |
|
} |
411 |
|
|
412 |
bool Condition::GetUnsafe() { |
bool Condition::GetUnsafe() { |
413 |
return bCondition; |
return bCondition; |
414 |
} |
} |