mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
bpo-41710: PyThread_acquire_lock_timed() clamps the timout (GH-28643)
PyThread_acquire_lock_timed() now clamps the timeout into the [_PyTime_MIN; _PyTime_MAX] range (_PyTime_t type) if it is too large, rather than calling Py_FatalError() which aborts the process. PyThread_acquire_lock_timed() no longer uses MICROSECONDS_TO_TIMESPEC() to compute sem_timedwait() argument, but _PyTime_GetSystemClock() and _PyTime_AsTimespec_truncate(). Fix _thread.TIMEOUT_MAX value on Windows: the maximum timeout is 0x7FFFFFFF milliseconds (around 24.9 days), not 0xFFFFFFFF milliseconds (around 49.7 days). Set PY_TIMEOUT_MAX to 0x7FFFFFFF milliseconds, rather than 0xFFFFFFFF milliseconds. Fix PY_TIMEOUT_MAX overflow test: replace (us >= PY_TIMEOUT_MAX) with (us > PY_TIMEOUT_MAX).
This commit is contained in:
parent
a143717003
commit
37b8294d62
9 changed files with 67 additions and 39 deletions
|
|
@ -292,6 +292,10 @@ PyThread_free_lock(PyThread_type_lock aLock)
|
|||
FreeNonRecursiveMutex(aLock) ;
|
||||
}
|
||||
|
||||
// WaitForSingleObject() documentation: "The time-out value needs to be a
|
||||
// positive number between 0 and 0x7FFFFFFF." INFINITE is equal to 0xFFFFFFFF.
|
||||
const DWORD TIMEOUT_MS_MAX = 0x7FFFFFFF;
|
||||
|
||||
/*
|
||||
* Return 1 on success if the lock was acquired
|
||||
*
|
||||
|
|
@ -309,10 +313,20 @@ PyThread_acquire_lock_timed(PyThread_type_lock aLock,
|
|||
|
||||
if (microseconds >= 0) {
|
||||
milliseconds = microseconds / 1000;
|
||||
if (microseconds % 1000 > 0)
|
||||
++milliseconds;
|
||||
if (milliseconds > PY_DWORD_MAX) {
|
||||
Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
|
||||
// Round milliseconds away from zero
|
||||
if (microseconds % 1000 > 0) {
|
||||
milliseconds++;
|
||||
}
|
||||
if (milliseconds > (PY_TIMEOUT_T)TIMEOUT_MS_MAX) {
|
||||
// bpo-41710: PyThread_acquire_lock_timed() cannot report timeout
|
||||
// overflow to the caller, so clamp the timeout to
|
||||
// [0, TIMEOUT_MS_MAX] milliseconds.
|
||||
//
|
||||
// TIMEOUT_MS_MAX milliseconds is around 24.9 days.
|
||||
//
|
||||
// _thread.Lock.acquire() and _thread.RLock.acquire() raise an
|
||||
// OverflowError if microseconds is greater than PY_TIMEOUT_MAX.
|
||||
milliseconds = TIMEOUT_MS_MAX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue