# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_atomic.h" // _Py_atomic_address
#include <signal.h> // NSIG
#define INVALID_FD (-1)
struct _signals_runtime_state {
- volatile struct {
- _Py_atomic_int tripped;
- /* func is atomic to ensure that PyErr_SetInterrupt is async-signal-safe
- * (even though it would probably be otherwise, anyway).
- */
- _Py_atomic_address func;
+ struct {
+ // tripped and func should be accessed using atomic ops.
+ int tripped;
+ PyObject* func;
} handlers[Py_NSIG];
volatile struct {
#endif
} wakeup;
- /* Speed up sigcheck() when none tripped */
- _Py_atomic_int is_tripped;
+ /* Speed up sigcheck() when none tripped.
+ is_tripped should be accessed using atomic ops. */
+ int is_tripped;
/* These objects necessarily belong to the main interpreter. */
PyObject *default_handler;
/* XXX Signals should be recorded per thread, now we have thread state. */
#include "Python.h"
-#include "pycore_atomic.h" // _Py_atomic_int
#include "pycore_call.h" // _PyObject_Call()
#include "pycore_ceval.h" // _PyEval_SignalReceived()
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
Py_LOCAL_INLINE(PyObject *)
get_handler(int i)
{
- return (PyObject *)_Py_atomic_load(&Handlers[i].func);
+ return (PyObject *)_Py_atomic_load_ptr(&Handlers[i].func);
}
Py_LOCAL_INLINE(void)
set_handler(int i, PyObject* func)
{
- _Py_atomic_store(&Handlers[i].func, (uintptr_t)func);
+ /* Store func with atomic operation to ensure
+ that PyErr_SetInterrupt is async-signal-safe. */
+ _Py_atomic_store_ptr(&Handlers[i].func, func);
}
static void
trip_signal(int sig_num)
{
- _Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1);
+ _Py_atomic_store_int(&Handlers[sig_num].tripped, 1);
/* Set is_tripped after setting .tripped, as it gets
cleared in PyErr_CheckSignals() before .tripped. */
- _Py_atomic_store(&is_tripped, 1);
+ _Py_atomic_store_int(&is_tripped, 1);
/* Signals are always handled by the main interpreter */
PyInterpreterState *interp = _PyInterpreterState_Main();
// Restore default signals and clear handlers
for (int signum = 1; signum < Py_NSIG; signum++) {
PyObject *func = get_handler(signum);
- _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
+ _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0);
set_handler(signum, NULL);
if (func != NULL
&& func != Py_None
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
{
_Py_CHECK_EMSCRIPTEN_SIGNALS();
- if (!_Py_atomic_load(&is_tripped)) {
+ if (!_Py_atomic_load_int(&is_tripped)) {
return 0;
}
* we receive a signal i after we zero is_tripped and before we
* check Handlers[i].tripped.
*/
- _Py_atomic_store(&is_tripped, 0);
+ _Py_atomic_store_int(&is_tripped, 0);
_PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate);
signal_state_t *state = &signal_global_state;
for (int i = 1; i < Py_NSIG; i++) {
- if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) {
+ if (!_Py_atomic_load_int_relaxed(&Handlers[i].tripped)) {
continue;
}
- _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
+ _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0);
/* Signal handlers can be modified while a signal is received,
* and therefore the fact that trip_signal() or PyErr_SetInterrupt()
}
if (!result) {
/* On error, re-schedule a call to _PyErr_CheckSignalsTstate() */
- _Py_atomic_store(&is_tripped, 1);
+ _Py_atomic_store_int(&is_tripped, 1);
return -1;
}
#endif
for (int signum = 1; signum < Py_NSIG; signum++) {
- _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
+ _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0);
}
if (install_signal_handlers) {
return 0;
}
- if (!_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
+ if (!_Py_atomic_load_int_relaxed(&Handlers[SIGINT].tripped)) {
return 0;
}
- _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
+ _Py_atomic_store_int_relaxed(&Handlers[SIGINT].tripped, 0);
return 1;
}
static void
_clear_pending_signals(void)
{
- if (!_Py_atomic_load(&is_tripped)) {
+ if (!_Py_atomic_load_int(&is_tripped)) {
return;
}
- _Py_atomic_store(&is_tripped, 0);
+ _Py_atomic_store_int(&is_tripped, 0);
for (int i = 1; i < Py_NSIG; ++i) {
- _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
+ _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0);
}
}