summaryrefslogtreecommitdiffstats
path: root/Modules/_threadmodule.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 /Modules/_threadmodule.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 'Modules/_threadmodule.c')
-rw-r--r--Modules/_threadmodule.c52
1 files changed, 2 insertions, 50 deletions
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 86bd560..7620511 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -3,7 +3,6 @@
/* Interface to Sjoerd's portable C thread library */
#include "Python.h"
-#include "pycore_ceval.h" // _PyEval_MakePendingCalls()
#include "pycore_dict.h" // _PyDict_Pop()
#include "pycore_interp.h" // _PyInterpreterState.threads.count
#include "pycore_moduleobject.h" // _PyModule_GetState()
@@ -76,57 +75,10 @@ lock_dealloc(lockobject *self)
Py_DECREF(tp);
}
-/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
- * is interrupted, signal handlers are run, and if they raise an exception,
- * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
- * are returned, depending on whether the lock can be acquired within the
- * timeout.
- */
-static PyLockStatus
+static inline PyLockStatus
acquire_timed(PyThread_type_lock lock, _PyTime_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;
+ return PyThread_acquire_lock_timed_with_retries(lock, timeout);
}
static int