1// To enable signal handling, the embedder should:
2// 1. set Module.Py_EmscriptenSignalBuffer = some_shared_array_buffer;
3// 2. set the Py_EMSCRIPTEN_SIGNAL_HANDLING flag to 1 as follows:
4//    Module.HEAP8[Module._Py_EMSCRIPTEN_SIGNAL_HANDLING] = 1
5//
6// The address &Py_EMSCRIPTEN_SIGNAL_HANDLING is exported as
7// Module._Py_EMSCRIPTEN_SIGNAL_HANDLING.
8#include <emscripten.h>
9#include "Python.h"
10
11EM_JS(int, _Py_CheckEmscriptenSignals_Helper, (void), {
12    if (!Module.Py_EmscriptenSignalBuffer) {
13        return 0;
14    }
15    try {
16        let result = Module.Py_EmscriptenSignalBuffer[0];
17        Module.Py_EmscriptenSignalBuffer[0] = 0;
18        return result;
19    } catch(e) {
20#if !defined(NDEBUG)
21        console.warn("Error occurred while trying to read signal buffer:", e);
22#endif
23        return 0;
24    }
25});
26
27EMSCRIPTEN_KEEPALIVE int Py_EMSCRIPTEN_SIGNAL_HANDLING = 0;
28
29void
30_Py_CheckEmscriptenSignals(void)
31{
32    if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) {
33        return;
34    }
35    int signal = _Py_CheckEmscriptenSignals_Helper();
36    if (signal) {
37        PyErr_SetInterruptEx(signal);
38    }
39}
40
41
42#define PY_EMSCRIPTEN_SIGNAL_INTERVAL 50
43static int emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL;
44
45void
46_Py_CheckEmscriptenSignalsPeriodically(void)
47{
48    if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) {
49        return;
50    }
51    emscripten_signal_clock--;
52    if (emscripten_signal_clock == 0) {
53        emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL;
54        _Py_CheckEmscriptenSignals();
55    }
56}
57