mirror of
https://github.com/python/cpython
synced 2024-09-16 00:48:28 +00:00
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)
|
Py_LOCAL_INLINE(int)
|
||||||
PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us)
|
PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us)
|
||||||
{
|
{
|
||||||
struct timespec abs;
|
struct timespec abs_timeout;
|
||||||
_PyThread_cond_after(us, &abs);
|
_PyThread_cond_after(us, &abs_timeout);
|
||||||
int ret = pthread_cond_timedwait(cond, mut, &abs);
|
int ret = pthread_cond_timedwait(cond, mut, &abs_timeout);
|
||||||
if (ret == ETIMEDOUT) {
|
if (ret == ETIMEDOUT) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,19 +113,6 @@
|
||||||
#endif
|
#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
|
* pthread_cond support
|
||||||
*/
|
*/
|
||||||
|
@ -156,23 +143,23 @@ _PyThread_cond_init(PyCOND_T *cond)
|
||||||
return pthread_cond_init(cond, condattr_monotonic);
|
return pthread_cond_init(cond, condattr_monotonic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_PyThread_cond_after(long long us, struct timespec *abs)
|
_PyThread_cond_after(long long us, struct timespec *abs)
|
||||||
{
|
{
|
||||||
|
_PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us);
|
||||||
|
_PyTime_t t;
|
||||||
#ifdef CONDATTR_MONOTONIC
|
#ifdef CONDATTR_MONOTONIC
|
||||||
if (condattr_monotonic) {
|
if (condattr_monotonic) {
|
||||||
clock_gettime(CLOCK_MONOTONIC, abs);
|
t = _PyTime_GetMonotonicClock();
|
||||||
abs->tv_sec += us / 1000000;
|
|
||||||
abs->tv_nsec += (us % 1000000) * 1000;
|
|
||||||
abs->tv_sec += abs->tv_nsec / 1000000000;
|
|
||||||
abs->tv_nsec %= 1000000000;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
struct timespec ts;
|
t = _PyTime_GetSystemClock();
|
||||||
MICROSECONDS_TO_TIMESPEC(us, ts);
|
}
|
||||||
*abs = ts;
|
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;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timespec abs;
|
struct timespec abs_timeout;
|
||||||
if (microseconds > 0) {
|
if (microseconds > 0) {
|
||||||
_PyThread_cond_after(microseconds, &abs);
|
_PyThread_cond_after(microseconds, &abs_timeout);
|
||||||
}
|
}
|
||||||
// Continue trying until we get the lock
|
// 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) {
|
while (1) {
|
||||||
if (microseconds > 0) {
|
if (microseconds > 0) {
|
||||||
status = pthread_cond_timedwait(&thelock->lock_released,
|
status = pthread_cond_timedwait(&thelock->lock_released,
|
||||||
&thelock->mut, &abs);
|
&thelock->mut, &abs_timeout);
|
||||||
if (status == 1) {
|
if (status == 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue