mirror of https://github.com/python/cpython
gh-74953: _PyThread_cond_after() uses _PyTime_t (#94056)
pthread _PyThread_cond_after() implementation now uses the _PyTime_t type to handle properly overflow: clamp to the maximum value. Remove MICROSECONDS_TO_TIMESPEC() function.
This commit is contained in:
parent
616fa3465d
commit
c7a79bb036
|
@ -68,9 +68,9 @@ void _PyThread_cond_after(long long us, struct timespec *abs);
|
|||
Py_LOCAL_INLINE(int)
|
||||
PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us)
|
||||
{
|
||||
struct timespec abs;
|
||||
_PyThread_cond_after(us, &abs);
|
||||
int ret = pthread_cond_timedwait(cond, mut, &abs);
|
||||
struct timespec abs_timeout;
|
||||
_PyThread_cond_after(us, &abs_timeout);
|
||||
int ret = pthread_cond_timedwait(cond, mut, &abs_timeout);
|
||||
if (ret == ETIMEDOUT) {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -113,19 +113,6 @@
|
|||
#endif
|
||||
|
||||
|
||||
#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
|
||||
do { \
|
||||
struct timeval tv; \
|
||||
gettimeofday(&tv, NULL); \
|
||||
tv.tv_usec += microseconds % 1000000; \
|
||||
tv.tv_sec += microseconds / 1000000; \
|
||||
tv.tv_sec += tv.tv_usec / 1000000; \
|
||||
tv.tv_usec %= 1000000; \
|
||||
ts.tv_sec = tv.tv_sec; \
|
||||
ts.tv_nsec = tv.tv_usec * 1000; \
|
||||
} while(0)
|
||||
|
||||
|
||||
/*
|
||||
* pthread_cond support
|
||||
*/
|
||||
|
@ -156,23 +143,23 @@ _PyThread_cond_init(PyCOND_T *cond)
|
|||
return pthread_cond_init(cond, condattr_monotonic);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyThread_cond_after(long long us, struct timespec *abs)
|
||||
{
|
||||
_PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us);
|
||||
_PyTime_t t;
|
||||
#ifdef CONDATTR_MONOTONIC
|
||||
if (condattr_monotonic) {
|
||||
clock_gettime(CLOCK_MONOTONIC, abs);
|
||||
abs->tv_sec += us / 1000000;
|
||||
abs->tv_nsec += (us % 1000000) * 1000;
|
||||
abs->tv_sec += abs->tv_nsec / 1000000000;
|
||||
abs->tv_nsec %= 1000000000;
|
||||
return;
|
||||
t = _PyTime_GetMonotonicClock();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
struct timespec ts;
|
||||
MICROSECONDS_TO_TIMESPEC(us, ts);
|
||||
*abs = ts;
|
||||
{
|
||||
t = _PyTime_GetSystemClock();
|
||||
}
|
||||
t = _PyTime_Add(t, timeout);
|
||||
_PyTime_AsTimespec_clamp(t, abs);
|
||||
}
|
||||
|
||||
|
||||
|
@ -639,9 +626,9 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
struct timespec abs;
|
||||
struct timespec abs_timeout;
|
||||
if (microseconds > 0) {
|
||||
_PyThread_cond_after(microseconds, &abs);
|
||||
_PyThread_cond_after(microseconds, &abs_timeout);
|
||||
}
|
||||
// Continue trying until we get the lock
|
||||
|
||||
|
@ -649,7 +636,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
|
|||
while (1) {
|
||||
if (microseconds > 0) {
|
||||
status = pthread_cond_timedwait(&thelock->lock_released,
|
||||
&thelock->mut, &abs);
|
||||
&thelock->mut, &abs_timeout);
|
||||
if (status == 1) {
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue