mirror of
https://github.com/python/cpython.git
synced 2025-07-15 23:35:23 +00:00
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.)
This commit is contained in:
parent
e37620edfd
commit
a53d7cb672
5 changed files with 576 additions and 153 deletions
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue