mirror of https://github.com/python/cpython
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>
This commit is contained in:
parent
bdc4974965
commit
087d0fa5b9
|
@ -0,0 +1,25 @@
|
|||
#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
|
|
@ -429,7 +429,8 @@ PYTHON_OBJS= \
|
|||
Python/$(DYNLOADFILE) \
|
||||
$(LIBOBJS) \
|
||||
$(MACHDEP_OBJS) \
|
||||
$(DTRACE_OBJS)
|
||||
$(DTRACE_OBJS) \
|
||||
@PLATFORM_OBJS@
|
||||
|
||||
|
||||
##########################################################################
|
||||
|
@ -1608,6 +1609,7 @@ PYTHON_HEADERS= \
|
|||
$(srcdir)/Include/internal/pycore_unicodeobject.h \
|
||||
$(srcdir)/Include/internal/pycore_warnings.h \
|
||||
$(DTRACE_HEADERS) \
|
||||
@PLATFORM_HEADERS@ \
|
||||
\
|
||||
$(srcdir)/Python/stdlib_module_names.h
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
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.
|
|
@ -13,6 +13,7 @@
|
|||
#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"
|
||||
|
@ -1797,6 +1798,7 @@ PyErr_CheckSignals(void)
|
|||
int
|
||||
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
|
||||
{
|
||||
_Py_CHECK_EMSCRIPTEN_SIGNALS();
|
||||
if (!_Py_atomic_load(&is_tripped)) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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; \
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -817,6 +817,8 @@ TRUE
|
|||
MACHDEP_OBJS
|
||||
DYNLOADFILE
|
||||
DLINCLDIR
|
||||
PLATFORM_OBJS
|
||||
PLATFORM_HEADERS
|
||||
DTRACE_OBJS
|
||||
DTRACE_HEADERS
|
||||
DFLAGS
|
||||
|
@ -13993,6 +13995,21 @@ $as_echo "$ac_cv_dtrace_link" >&6; }
|
|||
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=.
|
||||
|
|
13
configure.ac
13
configure.ac
|
@ -4187,6 +4187,19 @@ then
|
|||
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=.
|
||||
|
|
Loading…
Reference in New Issue