summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-10-24 23:53:32 (GMT)
committerGitHub <noreply@github.com>2017-10-24 23:53:32 (GMT)
commit850a18e03e8f8309bc8c39adc6e7d51a4568cd9a (patch)
tree56455b89cb152566734d1fc5de5c70029c3baa70 /Include
parent3557b05c5a7dfd7d97ddfd3b79aefd53d25e5132 (diff)
downloadcpython-850a18e03e8f8309bc8c39adc6e7d51a4568cd9a.zip
cpython-850a18e03e8f8309bc8c39adc6e7d51a4568cd9a.tar.gz
cpython-850a18e03e8f8309bc8c39adc6e7d51a4568cd9a.tar.bz2
bpo-30768: Recompute timeout on interrupted lock (GH-4103)
Fix the pthread+semaphore implementation of PyThread_acquire_lock_timed() when called with timeout > 0 and intr_flag=0: recompute the timeout if sem_timedwait() is interrupted by a signal (EINTR). See also the PEP 475. The pthread implementation of PyThread_acquire_lock() now fails with a fatal error if the timeout is larger than PY_TIMEOUT_MAX, as done in the Windows implementation. The check prevents any risk of overflow in PyThread_acquire_lock(). Add also PY_DWORD_MAX constant.
Diffstat (limited to 'Include')
-rw-r--r--Include/pyport.h3
-rw-r--r--Include/pythread.h21
2 files changed, 17 insertions, 7 deletions
diff --git a/Include/pyport.h b/Include/pyport.h
index 2742e47..0e82543 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -787,6 +787,9 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler;
#include <android/api-level.h>
#endif
+/* Maximum value of the Windows DWORD type */
+#define PY_DWORD_MAX 4294967295U
+
/* This macro used to tell whether Python was built with multithreading
* enabled. Now multithreading is always enabled, but keep the macro
* for compatibility.
diff --git a/Include/pythread.h b/Include/pythread.h
index d667468..eb61033 100644
--- a/Include/pythread.h
+++ b/Include/pythread.h
@@ -42,16 +42,23 @@ PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int);
and floating-point numbers allowed.
*/
#define PY_TIMEOUT_T long long
-#define PY_TIMEOUT_MAX PY_LLONG_MAX
-/* In the NT API, the timeout is a DWORD and is expressed in milliseconds */
-#if defined (NT_THREADS)
-#if 0xFFFFFFFFLL * 1000 < PY_TIMEOUT_MAX
-#undef PY_TIMEOUT_MAX
-#define PY_TIMEOUT_MAX (0xFFFFFFFFLL * 1000)
-#endif
+#if defined(_POSIX_THREADS)
+ /* PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000),
+ convert microseconds to nanoseconds. */
+# define PY_TIMEOUT_MAX (PY_LLONG_MAX / 1000)
+#elif defined (NT_THREADS)
+ /* In the NT API, the timeout is a DWORD and is expressed in milliseconds */
+# if 0xFFFFFFFFLL * 1000 < PY_LLONG_MAX
+# define PY_TIMEOUT_MAX (0xFFFFFFFFLL * 1000)
+# else
+# define PY_TIMEOUT_MAX PY_LLONG_MAX
+# endif
+#else
+# define PY_TIMEOUT_MAX PY_LLONG_MAX
#endif
+
/* If microseconds == 0, the call is non-blocking: it returns immediately
even when the lock can't be acquired.
If microseconds > 0, the call waits up to the specified duration.