92
92
* mutexes and condition variables:
93
93
*/
94
94
#if (defined(_POSIX_SEMAPHORES ) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES ) && \
95
- defined(HAVE_SEM_TIMEDWAIT ))
95
+ ( defined(HAVE_SEM_TIMEDWAIT ) || defined( HAVE_SEM_CLOCKWAIT ) ))
96
96
# define USE_SEMAPHORES
97
97
#else
98
98
# undef USE_SEMAPHORES
@@ -461,17 +461,34 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
461
461
timeout = _PyTime_FromNanoseconds (-1 );
462
462
}
463
463
464
+ #ifdef HAVE_SEM_CLOCKWAIT
465
+ struct timespec abs_timeout ;
466
+ // Local scope for deadline
467
+ {
468
+ _PyTime_t deadline = _PyTime_GetMonotonicClock () + timeout ;
469
+ _PyTime_AsTimespec_clamp (deadline , & abs_timeout );
470
+ }
471
+ #else
464
472
_PyTime_t deadline = 0 ;
465
- if (timeout > 0 && !intr_flag ) {
473
+ if (timeout > 0
474
+ && !intr_flag
475
+ )
476
+ {
466
477
deadline = _PyTime_GetMonotonicClock () + timeout ;
467
478
}
479
+ #endif
468
480
469
481
while (1 ) {
470
482
if (timeout > 0 ) {
471
- _PyTime_t t = _PyTime_GetSystemClock () + timeout ;
483
+ #ifdef HAVE_SEM_CLOCKWAIT
484
+ status = fix_status (sem_clockwait (thelock , CLOCK_MONOTONIC ,
485
+ & abs_timeout ));
486
+ #else
487
+ _PyTime_t abs_timeout = _PyTime_GetSystemClock () + timeout ;
472
488
struct timespec ts ;
473
- _PyTime_AsTimespec_clamp (t , & ts );
489
+ _PyTime_AsTimespec_clamp (abs_timeout , & ts );
474
490
status = fix_status (sem_timedwait (thelock , & ts ));
491
+ #endif
475
492
}
476
493
else if (timeout == 0 ) {
477
494
status = fix_status (sem_trywait (thelock ));
@@ -486,6 +503,9 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
486
503
break ;
487
504
}
488
505
506
+ // sem_clockwait() uses an absolute timeout, there is no need
507
+ // to recompute the relative timeout.
508
+ #ifndef HAVE_SEM_CLOCKWAIT
489
509
if (timeout > 0 ) {
490
510
/* wait interrupted by a signal (EINTR): recompute the timeout */
491
511
_PyTime_t timeout = deadline - _PyTime_GetMonotonicClock ();
@@ -494,17 +514,24 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
494
514
break ;
495
515
}
496
516
}
517
+ #endif
497
518
}
498
519
499
520
/* Don't check the status if we're stopping because of an interrupt. */
500
521
if (!(intr_flag && status == EINTR )) {
501
522
if (timeout > 0 ) {
502
- if (status != ETIMEDOUT )
523
+ if (status != ETIMEDOUT ) {
524
+ #ifdef HAVE_SEM_CLOCKWAIT
525
+ CHECK_STATUS ("sem_clockwait" );
526
+ #else
503
527
CHECK_STATUS ("sem_timedwait" );
528
+ #endif
529
+ }
504
530
}
505
531
else if (timeout == 0 ) {
506
- if (status != EAGAIN )
532
+ if (status != EAGAIN ) {
507
533
CHECK_STATUS ("sem_trywait" );
534
+ }
508
535
}
509
536
else {
510
537
CHECK_STATUS ("sem_wait" );
0 commit comments