pyodide/cpython/patches/0012-Interrupt-handling.patch

122 lines
3.2 KiB
Diff

From 8e20fedad850985b0789bc3aa06281e6b1ef9528 Mon Sep 17 00:00:00 2001
From: Hood Chatham <roberthoodchatham@gmail.com>
Date: Wed, 30 Mar 2022 14:50:30 -0700
Subject: [PATCH 12/14] Interrupt handling
---
Modules/signalmodule.c | 38 ++++++++++++++++++++++++++++++++++++++
Python/ceval.c | 29 +++++++++++++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index c3a5237bce..9f7f707a82 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -1776,11 +1776,49 @@ PyErr_CheckSignals(void)
return _PyErr_CheckSignalsTstate(tstate);
}
+#if defined(__EMSCRIPTEN__)
+
+#include <emscripten.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);
+ }
+}
+
+#endif
/* Declared in cpython/pyerrors.h */
int
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
{
+ #if defined(__EMSCRIPTEN__)
+ _Py_CheckEmscriptenSignals();
+ #endif
+
if (!_Py_atomic_load(&is_tripped)) {
return 0;
}
diff --git a/Python/ceval.c b/Python/ceval.c
index ab10b4166d..98bc690fae 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1152,6 +1152,30 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
return _PyEval_EvalFrame(tstate, f, throwflag);
}
+#if defined(__EMSCRIPTEN__)
+
+extern int Py_EMSCRIPTEN_SIGNAL_HANDLING;
+void _Py_CheckEmscriptenSignals(void);
+
+#define PY_EMSCRIPTEN_SIGNAL_INTERVAL 50
+
+static int
+emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL;
+
+static void
+_Py_CheckEmscriptenSignalsPeriodically()
+{
+ if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) {
+ return;
+ }
+ emscripten_signal_clock--;
+ if (emscripten_signal_clock == 0) {
+ emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL;
+ _Py_CheckEmscriptenSignals();
+ }
+}
+
+#endif
/* Handle signals, pending calls, GIL drop request
and asynchronous exception */
@@ -1313,6 +1337,7 @@ eval_frame_handle_pending(PyThreadState *tstate)
#define CHECK_EVAL_BREAKER() \
+ _Py_CheckEmscriptenSignalsPeriodically(); \
if (_Py_atomic_load_relaxed(eval_breaker)) { \
continue; \
}
@@ -1742,6 +1767,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */
assert(!_PyErr_Occurred(tstate));
+ #if defined(__EMSCRIPTEN__)
+ _Py_CheckEmscriptenSignalsPeriodically();
+ #endif
+
/* Do periodic things. Doing this every time through
the loop would add too much overhead, so we do it
only every Nth instruction. We also do it if
--
2.25.1