aboutsummaryrefslogtreecommitdiff
path: root/src/threading.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/threading.c')
-rw-r--r--src/threading.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/threading.c b/src/threading.c
index 754b6d1..43e5f46 100644
--- a/src/threading.c
+++ b/src/threading.c
@@ -243,6 +243,8 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) {
243#endif 243#endif
244 244
245#if THREADAPI == THREADAPI_WINDOWS 245#if THREADAPI == THREADAPI_WINDOWS
246
247#if WINVER <= 0x0400 // Windows NT4: Use Mutexes with Events
246 // 248 //
247 void MUTEX_INIT( MUTEX_T *ref ) { 249 void MUTEX_INIT( MUTEX_T *ref ) {
248 *ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL ); 250 *ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL );
@@ -260,6 +262,8 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) {
260 if (!ReleaseMutex(*ref)) 262 if (!ReleaseMutex(*ref))
261 FAIL( "ReleaseMutex", GetLastError() ); 263 FAIL( "ReleaseMutex", GetLastError() );
262 } 264 }
265#endif // Windows NT4
266
263 /* MSDN: "If you would like to use the CRT in ThreadProc, use the 267 /* MSDN: "If you would like to use the CRT in ThreadProc, use the
264 _beginthreadex function instead (of CreateThread)." 268 _beginthreadex function instead (of CreateThread)."
265 MSDN: "you can create at most 2028 threads" 269 MSDN: "you can create at most 2028 threads"
@@ -354,6 +358,7 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs)
354#endif // !__GNUC__ 358#endif // !__GNUC__
355 } 359 }
356 360
361#if WINVER <= 0x0400 // Windows NT4: Use PulseEvent, although it is unreliable, but then...
357 362
358 // 363 //
359 void SIGNAL_INIT( SIGNAL_T *ref ) { 364 void SIGNAL_INIT( SIGNAL_T *ref ) {
@@ -426,6 +431,66 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs)
426 if (!PulseEvent( *ref )) 431 if (!PulseEvent( *ref ))
427 FAIL( "PulseEvent", GetLastError() ); 432 FAIL( "PulseEvent", GetLastError() );
428 } 433 }
434
435#else // Windows Vista and above: condition variables exist, use them
436
437 //
438 void SIGNAL_INIT( SIGNAL_T *ref )
439 {
440 InitializeConditionVariable( ref);
441 }
442
443 void SIGNAL_FREE( SIGNAL_T *ref )
444 {
445 // nothing to do
446 ref;
447 }
448
449 bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu_ref, time_d abs_secs)
450 {
451 long ms;
452
453 if( abs_secs < 0.0)
454 ms = INFINITE;
455 else if( abs_secs == 0.0)
456 ms = 0;
457 else
458 {
459 ms = (long) ((abs_secs - now_secs())*1000.0 + 0.5);
460
461 // If the time already passed, still try once (ms==0). A short timeout
462 // may have turned negative or 0 because of the two time samples done.
463 //
464 if( ms < 0)
465 ms = 0;
466 }
467
468 if( !SleepConditionVariableCS( ref, mu_ref, ms))
469 {
470 if( GetLastError() == ERROR_TIMEOUT)
471 {
472 return FALSE;
473 }
474 else
475 {
476 FAIL( "SleepConditionVariableCS", GetLastError());
477 }
478 }
479 return TRUE;
480 }
481
482 void SIGNAL_ONE( SIGNAL_T *ref )
483 {
484 WakeConditionVariable( ref);
485 }
486
487 void SIGNAL_ALL( SIGNAL_T *ref )
488 {
489 WakeAllConditionVariable( ref);
490 }
491
492#endif // Windows Vista and above
493
429#else // THREADAPI == THREADAPI_PTHREAD 494#else // THREADAPI == THREADAPI_PTHREAD
430 // PThread (Linux, OS X, ...) 495 // PThread (Linux, OS X, ...)
431 // 496 //