Skip to content

Commit 1b6b61d

Browse files
committed
Use _Py_atomic API for concurrency-sensitive signal state
1 parent b577db5 commit 1b6b61d

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

Modules/signalmodule.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static pid_t main_pid;
9393
#endif
9494

9595
static volatile struct {
96-
sig_atomic_t tripped;
96+
_Py_atomic_int tripped;
9797
PyObject *func;
9898
} Handlers[NSIG];
9999

@@ -113,7 +113,7 @@ static volatile sig_atomic_t wakeup_fd = -1;
113113
#endif
114114

115115
/* Speed up sigcheck() when none tripped */
116-
static volatile sig_atomic_t is_tripped = 0;
116+
static _Py_atomic_int is_tripped;
117117

118118
static PyObject *DefaultHandler;
119119
static PyObject *IgnoreHandler;
@@ -236,11 +236,13 @@ trip_signal(int sig_num)
236236
int fd;
237237
Py_ssize_t rc;
238238

239-
Handlers[sig_num].tripped = 1;
239+
_Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1);
240240

241241
/* Set is_tripped after setting .tripped, as it gets
242242
cleared in PyErr_CheckSignals() before .tripped. */
243-
is_tripped = 1;
243+
_Py_atomic_store(&is_tripped, 1);
244+
245+
/* Notify ceval.c */
244246
_PyEval_SignalReceived();
245247

246248
/* And then write to the wakeup fd *after* setting all the globals and
@@ -461,7 +463,7 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
461463
return NULL;
462464
}
463465
old_handler = Handlers[signalnum].func;
464-
Handlers[signalnum].tripped = 0;
466+
_Py_atomic_store_relaxed(&Handlers[signalnum].tripped, 0);
465467
Py_INCREF(handler);
466468
Handlers[signalnum].func = handler;
467469
if (old_handler != NULL)
@@ -1265,11 +1267,11 @@ PyInit__signal(void)
12651267
goto finally;
12661268
Py_INCREF(IntHandler);
12671269

1268-
Handlers[0].tripped = 0;
1270+
_Py_atomic_store_relaxed(&Handlers[0].tripped, 0);
12691271
for (i = 1; i < NSIG; i++) {
12701272
void (*t)(int);
12711273
t = PyOS_getsig(i);
1272-
Handlers[i].tripped = 0;
1274+
_Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
12731275
if (t == SIG_DFL)
12741276
Handlers[i].func = DefaultHandler;
12751277
else if (t == SIG_IGN)
@@ -1493,7 +1495,7 @@ finisignal(void)
14931495

14941496
for (i = 1; i < NSIG; i++) {
14951497
func = Handlers[i].func;
1496-
Handlers[i].tripped = 0;
1498+
_Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
14971499
Handlers[i].func = NULL;
14981500
if (i != SIGINT && func != NULL && func != Py_None &&
14991501
func != DefaultHandler && func != IgnoreHandler)
@@ -1514,7 +1516,7 @@ PyErr_CheckSignals(void)
15141516
int i;
15151517
PyObject *f;
15161518

1517-
if (!is_tripped)
1519+
if (!_Py_atomic_load(&is_tripped))
15181520
return 0;
15191521

15201522
#ifdef WITH_THREAD
@@ -1536,24 +1538,24 @@ PyErr_CheckSignals(void)
15361538
* we receive a signal i after we zero is_tripped and before we
15371539
* check Handlers[i].tripped.
15381540
*/
1539-
is_tripped = 0;
1541+
_Py_atomic_store(&is_tripped, 0);
15401542

15411543
if (!(f = (PyObject *)PyEval_GetFrame()))
15421544
f = Py_None;
15431545

15441546
for (i = 1; i < NSIG; i++) {
1545-
if (Handlers[i].tripped) {
1547+
if (_Py_atomic_load_relaxed(&Handlers[i].tripped)) {
15461548
PyObject *result = NULL;
15471549
PyObject *arglist = Py_BuildValue("(iO)", i, f);
1548-
Handlers[i].tripped = 0;
1550+
_Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
15491551

15501552
if (arglist) {
15511553
result = PyEval_CallObject(Handlers[i].func,
15521554
arglist);
15531555
Py_DECREF(arglist);
15541556
}
15551557
if (!result) {
1556-
is_tripped = 1;
1558+
_Py_atomic_store(&is_tripped, 1);
15571559
return -1;
15581560
}
15591561

@@ -1592,12 +1594,12 @@ PyOS_FiniInterrupts(void)
15921594
int
15931595
PyOS_InterruptOccurred(void)
15941596
{
1595-
if (Handlers[SIGINT].tripped) {
1597+
if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
15961598
#ifdef WITH_THREAD
15971599
if (PyThread_get_thread_ident() != main_thread)
15981600
return 0;
15991601
#endif
1600-
Handlers[SIGINT].tripped = 0;
1602+
_Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
16011603
return 1;
16021604
}
16031605
return 0;
@@ -1607,11 +1609,11 @@ static void
16071609
_clear_pending_signals(void)
16081610
{
16091611
int i;
1610-
if (!is_tripped)
1612+
if (!_Py_atomic_load(&is_tripped))
16111613
return;
1612-
is_tripped = 0;
1614+
_Py_atomic_store(&is_tripped, 0);
16131615
for (i = 1; i < NSIG; ++i) {
1614-
Handlers[i].tripped = 0;
1616+
_Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
16151617
}
16161618
}
16171619

0 commit comments

Comments
 (0)