This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Review usage of atomic variables in signamodule.c
Type: Stage:
Components: Interpreter Core Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ammar2, corona10, shihai1991, vstinner
Priority: normal Keywords:

Created on 2020-12-28 16:06 by vstinner, last changed 2022-04-11 14:59 by admin.

Messages (2)
msg383901 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-12-28 16:06
In bpo-41713, I ported the _signal module to the multi-phase initialization API. I tried to move the signal state into a structure to cleanup the code, but I was scared by the following atomic variables:
---------------
static volatile struct {
    _Py_atomic_int tripped;
    PyObject *func;
} Handlers[NSIG];

#ifdef MS_WINDOWS
#define INVALID_FD ((SOCKET_T)-1)

static volatile struct {
    SOCKET_T fd;
    int warn_on_full_buffer;
    int use_send;
} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0};
#else
#define INVALID_FD (-1)
static volatile struct {
#ifdef __VXWORKS__
    int fd;
#else
    sig_atomic_t fd;
#endif
    int warn_on_full_buffer;
} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1};
#endif

/* Speed up sigcheck() when none tripped */
static _Py_atomic_int is_tripped;
---------------

For me, the most surprising part is Handlers[signum].tripped which is declared as volatile *and* an atomic variable.

I'm not sure if Handlers[signum].func must be volatile neither.

Also, wakeup.fd is declared as sig_atomic_t on Unix. Could we use an atomic variable instead, or is it important to use "sig_atomic_t"?

--

I recently added pycore_atomic_funcs.h which provides functions to access variables atomically. It uses atomic functions if available, or falls back on "volatile" otherwise. Maybe this approach would be interesting here, maybe for Handlers[signum].func?
msg383923 - (view) Author: Ammar Askar (ammar2) * (Python committer) Date: 2020-12-28 19:57
> For me, the most surprising part is Handlers[signum].tripped which is declared as volatile *and* an atomic variable.

I think it's just following this part of the C spec (Some background in bpo-12060):

> or refers to any object with static storage duration other than by assigning a value to a static storage duration variable of type volatile sig_atomic_t. Furthermore, if such a call fails, the value of errno is unspecified.

https://pubs.opengroup.org/onlinepubs/007904875/functions/sigaction.html / https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers

> I'm not sure if Handlers[signum].func must be volatile neither.

I think your assessment here is right considering it's never used in the signal handler itself.

> Also, wakeup.fd is declared as sig_atomic_t on Unix. Could we use an atomic variable instead, or is it important to use "sig_atomic_t"?

Again looking at the https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers recommendation it seems like using an atomic variable is fine but only if it's lock-free.
History
Date User Action Args
2022-04-11 14:59:39adminsetgithub: 86933
2020-12-28 19:57:57ammar2setnosy: + ammar2
messages: + msg383923
2020-12-28 16:52:07shihai1991setnosy: + shihai1991
2020-12-28 16:23:25corona10setnosy: + corona10
2020-12-28 16:06:14vstinnercreate