4 ms·
This isn't really a signals problem. This is a fundamentally racy API. Any decision of the form "go to sleep until this condition is true" can't be done relia
by ajross 3y ago
This isn't really a signals problem. This is a fundamentally racy API. Any decision of the form "go to sleep until this condition is true" can't be done reliably unless the code that decides "this condition" is atomic with respect to the entrance to the sleep state. That is, if the condition might change after you've decided it's false but before you suspend, you might never wake up.
There are lots of solutions to this. Synchronizing along a "queue" a-la file descriptors or semaphores is the most common. The generalization of this "suspend until" problem is captured by the "condition variable" abstraction, which combines the sleep with a lock that provides mutual exclusion and can be released atomically on suspend.
But the pause() system call didn't understand any of that, so it's unresolvably buggy without some extra layer somewhere to act as a backstop and wake up incorrectly-sleeping processes.
- Arch-TK 3y agopause() is fine, as long as you don't do it conditionally.
- ajross 3y agoWhat's a "non-conditional" pause though? Doing it in a main loop is still adjacent to a "while(something_to_do)" which isn't synchronized. I mean, yes, there are circumstances where you don't need a full condition variable. But those tend to be fragile and not subject to "just follow this one rule" design principles, and so should be avoided. Broadly I stand by the point: pause() as designed was a mistake and you shouldn't touch it. If you want signals to integrate into your main loop use signalfd() instead.
- Arch-TK 3y agoIf everything you wish to achieve in response to a signal can be achieved within the signal handler, you do not need a condition. Just `while (1) pause();`. Granted, this isn't a very common situation, but I can imagine a few use-cases.