summaryrefslogtreecommitdiffstats
path: root/Python/ceval_gil.c
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-01-23 18:08:23 (GMT)
committerGitHub <noreply@github.com>2024-01-23 18:08:23 (GMT)
commit441affc9e7f419ef0b68f734505fa2f79fe653c7 (patch)
tree1c7771190fffc7927ab70f485500521a96de7938 /Python/ceval_gil.c
parent5f1997896d9c3ecf92e9863177c452b468a6a2c8 (diff)
downloadcpython-441affc9e7f419ef0b68f734505fa2f79fe653c7.zip
cpython-441affc9e7f419ef0b68f734505fa2f79fe653c7.tar.gz
cpython-441affc9e7f419ef0b68f734505fa2f79fe653c7.tar.bz2
gh-111964: Implement stop-the-world pauses (gh-112471)
The `--disable-gil` builds occasionally need to pause all but one thread. Some examples include: * Cyclic garbage collection, where this is often called a "stop the world event" * Before calling `fork()`, to ensure a consistent state for internal data structures * During interpreter shutdown, to ensure that daemon threads aren't accessing Python objects This adds the following functions to implement global and per-interpreter pauses: * `_PyEval_StopTheWorldAll()` and `_PyEval_StartTheWorldAll()` (for the global runtime) * `_PyEval_StopTheWorld()` and `_PyEval_StartTheWorld()` (per-interpreter) (The function names may change.) These functions are no-ops outside of the `--disable-gil` build.
Diffstat (limited to 'Python/ceval_gil.c')
-rw-r--r--Python/ceval_gil.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c
index d70abbc..f3b1692 100644
--- a/Python/ceval_gil.c
+++ b/Python/ceval_gil.c
@@ -949,6 +949,15 @@ _Py_HandlePending(PyThreadState *tstate)
{
PyInterpreterState *interp = tstate->interp;
+ /* Stop-the-world */
+ if (_Py_eval_breaker_bit_is_set(interp, _PY_EVAL_PLEASE_STOP_BIT)) {
+ _Py_set_eval_breaker_bit(interp, _PY_EVAL_PLEASE_STOP_BIT, 0);
+ _PyThreadState_Suspend(tstate);
+
+ /* The attach blocks until the stop-the-world event is complete. */
+ _PyThreadState_Attach(tstate);
+ }
+
/* Pending signals */
if (_Py_eval_breaker_bit_is_set(interp, _PY_SIGNALS_PENDING_BIT)) {
if (handle_signals(tstate) != 0) {