diff options
author | Hood Chatham <roberthoodchatham@gmail.com> | 2022-04-03 20:58:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-03 20:58:52 (GMT) |
commit | 087d0fa5b97796560c0d8ceab4f0360fd54baf4f (patch) | |
tree | 975274b43e0cc50d11f70ba0c6a8fd344d74d632 /Python | |
parent | bdc497496548e30fa208a8d98c30bf6d1833ac4c (diff) | |
download | cpython-087d0fa5b97796560c0d8ceab4f0360fd54baf4f.zip cpython-087d0fa5b97796560c0d8ceab4f0360fd54baf4f.tar.gz cpython-087d0fa5b97796560c0d8ceab4f0360fd54baf4f.tar.bz2 |
bpo-47176: Interrupt handling for wasm32-emscripten builds without pthreads (GH-32209)
Co-authored-by: Christian Heimes <christian@python.org>
Co-authored-by: Brett Cannon <brett@python.org>
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 2 | ||||
-rw-r--r-- | Python/emscripten_signal.c | 56 |
2 files changed, 58 insertions, 0 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 43080f8..68d2920 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -21,6 +21,7 @@ #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "code.h" #include "pycore_dict.h" @@ -1292,6 +1293,7 @@ eval_frame_handle_pending(PyThreadState *tstate) } #define CHECK_EVAL_BREAKER() \ + _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \ if (_Py_atomic_load_relaxed(eval_breaker)) { \ goto handle_eval_breaker; \ } diff --git a/Python/emscripten_signal.c b/Python/emscripten_signal.c new file mode 100644 index 0000000..d617ddf --- /dev/null +++ b/Python/emscripten_signal.c @@ -0,0 +1,56 @@ +// To enable signal handling, the embedder should: +// 1. set Module.Py_EmscriptenSignalBuffer = some_shared_array_buffer; +// 2. set the Py_EMSCRIPTEN_SIGNAL_HANDLING flag to 1 as follows: +// Module.HEAP8[Module._Py_EMSCRIPTEN_SIGNAL_HANDLING] = 1 +// +// The address &Py_EMSCRIPTEN_SIGNAL_HANDLING is exported as +// Module._Py_EMSCRIPTEN_SIGNAL_HANDLING. +#include <emscripten.h> +#include "Python.h" + +EM_JS(int, _Py_CheckEmscriptenSignals_Helper, (void), { + if (!Module.Py_EmscriptenSignalBuffer) { + return 0; + } + try { + let result = Module.Py_EmscriptenSignalBuffer[0]; + Module.Py_EmscriptenSignalBuffer[0] = 0; + return result; + } catch(e) { +#if !defined(NDEBUG) + console.warn("Error occurred while trying to read signal buffer:", e); +#endif + return 0; + } +}); + +EMSCRIPTEN_KEEPALIVE int Py_EMSCRIPTEN_SIGNAL_HANDLING = 0; + +void +_Py_CheckEmscriptenSignals(void) +{ + if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) { + return; + } + int signal = _Py_CheckEmscriptenSignals_Helper(); + if (signal) { + PyErr_SetInterruptEx(signal); + } +} + + +#define PY_EMSCRIPTEN_SIGNAL_INTERVAL 50 +static int emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL; + +void +_Py_CheckEmscriptenSignalsPeriodically(void) +{ + if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) { + return; + } + emscripten_signal_clock--; + if (emscripten_signal_clock == 0) { + emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL; + _Py_CheckEmscriptenSignals(); + } +} |