diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/thread_pthread.h | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 3815ffa..9b5e273 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -92,7 +92,7 @@ * mutexes and condition variables: */ #if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \ - defined(HAVE_SEM_TIMEDWAIT)) + (defined(HAVE_SEM_TIMEDWAIT) || defined(HAVE_SEM_CLOCKWAIT))) # define USE_SEMAPHORES #else # undef USE_SEMAPHORES @@ -461,17 +461,34 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, timeout = _PyTime_FromNanoseconds(-1); } +#ifdef HAVE_SEM_CLOCKWAIT + struct timespec abs_timeout; + // Local scope for deadline + { + _PyTime_t deadline = _PyTime_GetMonotonicClock() + timeout; + _PyTime_AsTimespec_clamp(deadline, &abs_timeout); + } +#else _PyTime_t deadline = 0; - if (timeout > 0 && !intr_flag) { + if (timeout > 0 + && !intr_flag + ) + { deadline = _PyTime_GetMonotonicClock() + timeout; } +#endif while (1) { if (timeout > 0) { - _PyTime_t t = _PyTime_GetSystemClock() + timeout; +#ifdef HAVE_SEM_CLOCKWAIT + status = fix_status(sem_clockwait(thelock, CLOCK_MONOTONIC, + &abs_timeout)); +#else + _PyTime_t abs_timeout = _PyTime_GetSystemClock() + timeout; struct timespec ts; - _PyTime_AsTimespec_clamp(t, &ts); + _PyTime_AsTimespec_clamp(abs_timeout, &ts); status = fix_status(sem_timedwait(thelock, &ts)); +#endif } else if (timeout == 0) { status = fix_status(sem_trywait(thelock)); @@ -486,6 +503,9 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, break; } + // sem_clockwait() uses an absolute timeout, there is no need + // to recompute the relative timeout. +#ifndef HAVE_SEM_CLOCKWAIT if (timeout > 0) { /* wait interrupted by a signal (EINTR): recompute the timeout */ _PyTime_t timeout = deadline - _PyTime_GetMonotonicClock(); @@ -494,17 +514,24 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, break; } } +#endif } /* Don't check the status if we're stopping because of an interrupt. */ if (!(intr_flag && status == EINTR)) { if (timeout > 0) { - if (status != ETIMEDOUT) + if (status != ETIMEDOUT) { +#ifdef HAVE_SEM_CLOCKWAIT + CHECK_STATUS("sem_clockwait"); +#else CHECK_STATUS("sem_timedwait"); +#endif + } } else if (timeout == 0) { - if (status != EAGAIN) + if (status != EAGAIN) { CHECK_STATUS("sem_trywait"); + } } else { CHECK_STATUS("sem_wait"); |