diff options
| author | Sam Gross <colesbury@gmail.com> | 2024-01-23 18:08:23 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-23 18:08:23 (GMT) |
| commit | 441affc9e7f419ef0b68f734505fa2f79fe653c7 (patch) | |
| tree | 1c7771190fffc7927ab70f485500521a96de7938 /Python/ceval_gil.c | |
| parent | 5f1997896d9c3ecf92e9863177c452b468a6a2c8 (diff) | |
| download | cpython-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.c | 9 |
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) { |
