--- /dev/null
+#ifndef Py_EMSCRIPTEN_SIGNAL_H
+#define Py_EMSCRIPTEN_SIGNAL_H
+
+#if defined(__EMSCRIPTEN__)
+
+void
+_Py_CheckEmscriptenSignals(void);
+
+void
+_Py_CheckEmscriptenSignalsPeriodically(void);
+
+#define _Py_CHECK_EMSCRIPTEN_SIGNALS() _Py_CheckEmscriptenSignals()
+
+#define _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY() _Py_CheckEmscriptenSignalsPeriodically()
+
+extern int Py_EMSCRIPTEN_SIGNAL_HANDLING;
+
+#else
+
+#define _Py_CHECK_EMSCRIPTEN_SIGNALS()
+#define _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY()
+
+#endif // defined(__EMSCRIPTEN__)
+
+#endif // ndef Py_EMSCRIPTEN_SIGNAL_H
Python/$(DYNLOADFILE) \
$(LIBOBJS) \
$(MACHDEP_OBJS) \
- $(DTRACE_OBJS)
+ $(DTRACE_OBJS) \
+ @PLATFORM_OBJS@
##########################################################################
$(srcdir)/Include/internal/pycore_unicodeobject.h \
$(srcdir)/Include/internal/pycore_warnings.h \
$(DTRACE_HEADERS) \
+ @PLATFORM_HEADERS@ \
\
$(srcdir)/Python/stdlib_module_names.h
--- /dev/null
+Emscripten builds cannot handle signals in the usual way due to platform
+limitations. Python can now handle signals. To use, set
+Module.Py_EmscriptenSignalBuffer to be a single byte SharedArrayBuffer and
+set Py_EMSCRIPTEN_SIGNAL_HANDLING to 1. Writing a number into the
+SharedArrayBuffer will cause the corresponding signal to be raised into the
+Python thread.
#include "pycore_pyerrors.h" // _PyErr_SetString()
#include "pycore_pylifecycle.h" // NSIG
#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
#ifndef MS_WINDOWS
# include "posixmodule.h"
int
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
{
+ _Py_CHECK_EMSCRIPTEN_SIGNALS();
if (!_Py_atomic_load(&is_tripped)) {
return 0;
}
#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"
}
#define CHECK_EVAL_BREAKER() \
+ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \
if (_Py_atomic_load_relaxed(eval_breaker)) { \
goto handle_eval_breaker; \
}
--- /dev/null
+// 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();
+ }
+}
MACHDEP_OBJS
DYNLOADFILE
DLINCLDIR
+PLATFORM_OBJS
+PLATFORM_HEADERS
DTRACE_OBJS
DTRACE_HEADERS
DFLAGS
fi
fi
+PLATFORM_HEADERS=
+PLATFORM_OBJS=
+
+case $ac_sys_system in #(
+ Emscripten) :
+
+ as_fn_append PLATFORM_OBJS ' Python/emscripten_signal.o'
+ as_fn_append PLATFORM_HEADERS ' $(srcdir)/Include/internal/pycore_emscripten_signal.h'
+ ;; #(
+ *) :
+ ;;
+esac
+
+
+
# -I${DLINCLDIR} is added to the compile rule for importdl.o
DLINCLDIR=.
fi
fi
+dnl Platform-specific C and header files.
+PLATFORM_HEADERS=
+PLATFORM_OBJS=
+
+AS_CASE([$ac_sys_system],
+ [Emscripten], [
+ AS_VAR_APPEND([PLATFORM_OBJS], [' Python/emscripten_signal.o'])
+ AS_VAR_APPEND([PLATFORM_HEADERS], [' $(srcdir)/Include/internal/pycore_emscripten_signal.h'])
+ ],
+)
+AC_SUBST([PLATFORM_HEADERS])
+AC_SUBST([PLATFORM_OBJS])
+
# -I${DLINCLDIR} is added to the compile rule for importdl.o
AC_SUBST(DLINCLDIR)
DLINCLDIR=.