If you’re lucky enough to structure your entire app in advance to keep in mind how sync signals are delivered, you can ususllly get away with only setting an atomic Boolean, incrementing an atomic int, or setting a binary semaphore.
The presence of signals in UNIX made me reach the following conclusion: event loop should be mandatory (or at least opt-out), something setup in the CRT before main(). Of course, we're not living in such a well-made C world.