Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions Include/pythread.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock);
convert microseconds to nanoseconds. */
# define PY_TIMEOUT_MAX (LLONG_MAX / 1000)
#elif defined (NT_THREADS)
/* In the NT API, the timeout is a DWORD and is expressed in milliseconds */
# if 0xFFFFFFFFLL * 1000 < LLONG_MAX
# define PY_TIMEOUT_MAX (0xFFFFFFFFLL * 1000)
/* In the NT API, the timeout is a DWORD and is expressed in milliseconds,
* a positive number between 0 and 0x7FFFFFFF (see WaitForSingleObject()
* documentation). */
# if 0x7FFFFFFFLL * 1000 < LLONG_MAX
# define PY_TIMEOUT_MAX (0x7FFFFFFFLL * 1000)
# else
# define PY_TIMEOUT_MAX LLONG_MAX
# endif
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix :data:`_thread.TIMEOUT_MAX` value on Windows: the maximum timeout is
0x7FFFFFFF milliseconds (around 24.9 days), not 0xFFFFFFFF milliseconds (around
49.7 days).
12 changes: 9 additions & 3 deletions Python/thread_nt.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,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
*
Expand All @@ -312,9 +316,11 @@ PyThread_acquire_lock_timed(PyThread_type_lock aLock,

if (microseconds >= 0) {
milliseconds = microseconds / 1000;
if (microseconds % 1000 > 0)
++milliseconds;
if (milliseconds > PY_DWORD_MAX) {
// Round milliseconds away from zero
if (microseconds % 1000 > 0) {
milliseconds++;
}
if (milliseconds > (PY_TIMEOUT_T)TIMEOUT_MS_MAX) {
Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
}
}
Expand Down