mirror of https://github.com/pyodide/pyodide.git
122 lines
3.2 KiB
Diff
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
|
|
|