gh-109693: Use pyatomic.h for signal module by corona10 · Pull Request #110480 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions Include/internal/pycore_signal.h
35 changes: 18 additions & 17 deletions Modules/signalmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
/* 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
Expand Down Expand Up @@ -124,13 +123,15 @@ typedef struct {
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);
}


Expand Down Expand Up @@ -267,11 +268,11 @@ report_wakeup_send_error(void* data)
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();
Expand Down Expand Up @@ -1731,7 +1732,7 @@ _PySignal_Fini(void)
// 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
Expand Down Expand Up @@ -1785,7 +1786,7 @@ int
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
{
_Py_CHECK_EMSCRIPTEN_SIGNALS();
if (!_Py_atomic_load(&is_tripped)) {
if (!_Py_atomic_load_int(&is_tripped)) {
return 0;
}

Expand All @@ -1803,15 +1804,15 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
* 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()
Expand Down Expand Up @@ -1857,7 +1858,7 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
}
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;
}

Expand Down Expand Up @@ -1975,7 +1976,7 @@ _PySignal_Init(int install_signal_handlers)
#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) {
Expand All @@ -1997,11 +1998,11 @@ _PyOS_InterruptOccurred(PyThreadState *tstate)
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;
}

Expand All @@ -2019,13 +2020,13 @@ PyOS_InterruptOccurred(void)
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);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Python/ceval_gil.c