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) \
|
Python/$(DYNLOADFILE) \
|
||||||
$(LIBOBJS) \
|
$(LIBOBJS) \
|
||||||
$(MACHDEP_OBJS) \
|
$(MACHDEP_OBJS) \
|
||||||
$(DTRACE_OBJS)
|
$(DTRACE_OBJS) \
|
||||||
|
@PLATFORM_OBJS@
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
@ -1608,6 +1609,7 @@ PYTHON_HEADERS= \
|
||||||
$(srcdir)/Include/internal/pycore_unicodeobject.h \
|
$(srcdir)/Include/internal/pycore_unicodeobject.h \
|
||||||
$(srcdir)/Include/internal/pycore_warnings.h \
|
$(srcdir)/Include/internal/pycore_warnings.h \
|
||||||
$(DTRACE_HEADERS) \
|
$(DTRACE_HEADERS) \
|
||||||
|
@PLATFORM_HEADERS@ \
|
||||||
\
|
\
|
||||||
$(srcdir)/Python/stdlib_module_names.h
|
$(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_pyerrors.h" // _PyErr_SetString()
|
||||||
#include "pycore_pylifecycle.h" // NSIG
|
#include "pycore_pylifecycle.h" // NSIG
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
|
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
|
||||||
|
|
||||||
#ifndef MS_WINDOWS
|
#ifndef MS_WINDOWS
|
||||||
# include "posixmodule.h"
|
# include "posixmodule.h"
|
||||||
|
@ -1797,6 +1798,7 @@ PyErr_CheckSignals(void)
|
||||||
int
|
int
|
||||||
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
|
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
|
_Py_CHECK_EMSCRIPTEN_SIGNALS();
|
||||||
if (!_Py_atomic_load(&is_tripped)) {
|
if (!_Py_atomic_load(&is_tripped)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||||
#include "pycore_sysmodule.h" // _PySys_Audit()
|
#include "pycore_sysmodule.h" // _PySys_Audit()
|
||||||
#include "pycore_tuple.h" // _PyTuple_ITEMS()
|
#include "pycore_tuple.h" // _PyTuple_ITEMS()
|
||||||
|
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
|
||||||
|
|
||||||
#include "code.h"
|
#include "code.h"
|
||||||
#include "pycore_dict.h"
|
#include "pycore_dict.h"
|
||||||
|
@ -1292,6 +1293,7 @@ eval_frame_handle_pending(PyThreadState *tstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_EVAL_BREAKER() \
|
#define CHECK_EVAL_BREAKER() \
|
||||||
|
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \
|
||||||
if (_Py_atomic_load_relaxed(eval_breaker)) { \
|
if (_Py_atomic_load_relaxed(eval_breaker)) { \
|
||||||
goto handle_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
|
MACHDEP_OBJS
|
||||||
DYNLOADFILE
|
DYNLOADFILE
|
||||||
DLINCLDIR
|
DLINCLDIR
|
||||||
|
PLATFORM_OBJS
|
||||||
|
PLATFORM_HEADERS
|
||||||
DTRACE_OBJS
|
DTRACE_OBJS
|
||||||
DTRACE_HEADERS
|
DTRACE_HEADERS
|
||||||
DFLAGS
|
DFLAGS
|
||||||
|
@ -13993,6 +13995,21 @@ $as_echo "$ac_cv_dtrace_link" >&6; }
|
||||||
fi
|
fi
|
||||||
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
|
# -I${DLINCLDIR} is added to the compile rule for importdl.o
|
||||||
|
|
||||||
DLINCLDIR=.
|
DLINCLDIR=.
|
||||||
|
|
13
configure.ac
13
configure.ac
|
@ -4187,6 +4187,19 @@ then
|
||||||
fi
|
fi
|
||||||
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
|
# -I${DLINCLDIR} is added to the compile rule for importdl.o
|
||||||
AC_SUBST(DLINCLDIR)
|
AC_SUBST(DLINCLDIR)
|
||||||
DLINCLDIR=.
|
DLINCLDIR=.
|
||||||
|
|
Loading…
Reference in New Issue