Michael Paquier <michael@paquier.xyz> writes: > And then within separate signal handlers things like: > void > StatementCancelHandler(SIGNAL_ARGS) > { > [...] > signalPendingFlags |= PENDING_INTERRUPT | PENDING_CANCEL_QUERY; > [...] > }
AFAICS this still wouldn't work. The machine code is still going to look (on many machines) like "load from signalPendingFlags, OR in some bits, store to signalPendingFlags". So there's still a window for another signal handler to interrupt that and store some bits that will get lost.
You could only fix that by blocking all signal handling during the handler, which would be expensive and rather pointless.
I do not think that it's readily possible to improve on the current situation with one sig_atomic_t per flag.
After a fair bit of reading I think there are ways of doing this in C11 but I don't think those are portable to C99.
In C99 (and, in practice C89, as the C99 committee noted there were no known C89 implementations where reading was unsafe), reading or writing a static sig_atomic_t inside a signal handler is safe, but a round-trip is *not* guaranteed not to clobber. While I could be wrong, I think it is only in C11 that you have any round-trip operations which are guaranteed not to clobber in the language itself.
Basically we are a long way out to be able to consider these a single value as flags.
However, what I think one could do is use a struct of volatile sig_atomic_t members and macros for checking/setting. Simply writing a value is safe in C89 and higher.