diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2023-10-17 22:32:00 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-17 22:32:00 (GMT) |
commit | a53d7cb6729dc3f254b70afcf19eaf71a2eed540 (patch) | |
tree | 679f68637995e4bfefc98f0ec40edac6150693cd /Python/thread.c | |
parent | e37620edfd77b78b913b5eab55cd91327c3e7fd3 (diff) | |
download | cpython-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.c | 50 |
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. |