summaryrefslogtreecommitdiffstats
path: root/Python/thread.c
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2023-10-17 22:32:00 (GMT)
committerGitHub <noreply@github.com>2023-10-17 22:32:00 (GMT)
commita53d7cb6729dc3f254b70afcf19eaf71a2eed540 (patch)
tree679f68637995e4bfefc98f0ec40edac6150693cd /Python/thread.c
parente37620edfd77b78b913b5eab55cd91327c3e7fd3 (diff)
downloadcpython-a53d7cb6729dc3f254b70afcf19eaf71a2eed540.zip
cpython-a53d7cb6729dc3f254b70afcf19eaf71a2eed540.tar.gz
cpython-a53d7cb6729dc3f254b70afcf19eaf71a2eed540.tar.bz2
gh-84570: Send-Wait Fixes for _xxinterpchannels (gh-111006)
There were a few things I did in gh-110565 that need to be fixed. I also forgot to add tests in that PR. (Note that this PR exposes a refleak introduced by gh-110246. I'll take care of that separately.)
Diffstat (limited to 'Python/thread.c')
-rw-r--r--Python/thread.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/Python/thread.c b/Python/thread.c
index bf207ce..7185dd4 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -6,6 +6,7 @@
Stuff shared by all thread_*.h files is collected here. */
#include "Python.h"
+#include "pycore_ceval.h" // _PyEval_MakePendingCalls()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
#include "pycore_pythread.h" // _POSIX_THREADS
@@ -92,6 +93,55 @@ PyThread_set_stacksize(size_t size)
}
+PyLockStatus
+PyThread_acquire_lock_timed_with_retries(PyThread_type_lock lock,
+ PY_TIMEOUT_T timeout)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _PyTime_t endtime = 0;
+ if (timeout > 0) {
+ endtime = _PyDeadline_Init(timeout);
+ }
+
+ PyLockStatus r;
+ do {
+ _PyTime_t microseconds;
+ microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
+
+ /* first a simple non-blocking try without releasing the GIL */
+ r = PyThread_acquire_lock_timed(lock, 0, 0);
+ if (r == PY_LOCK_FAILURE && microseconds != 0) {
+ Py_BEGIN_ALLOW_THREADS
+ r = PyThread_acquire_lock_timed(lock, microseconds, 1);
+ Py_END_ALLOW_THREADS
+ }
+
+ if (r == PY_LOCK_INTR) {
+ /* Run signal handlers if we were interrupted. Propagate
+ * exceptions from signal handlers, such as KeyboardInterrupt, by
+ * passing up PY_LOCK_INTR. */
+ if (_PyEval_MakePendingCalls(tstate) < 0) {
+ return PY_LOCK_INTR;
+ }
+
+ /* If we're using a timeout, recompute the timeout after processing
+ * signals, since those can take time. */
+ if (timeout > 0) {
+ timeout = _PyDeadline_Get(endtime);
+
+ /* Check for negative values, since those mean block forever.
+ */
+ if (timeout < 0) {
+ r = PY_LOCK_FAILURE;
+ }
+ }
+ }
+ } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
+
+ return r;
+}
+
+
/* Thread Specific Storage (TSS) API
Cross-platform components of TSS API implementation.