pselect() on Linux does not deliver signals if events are pending pselect() on Linux does not deliver signals if events are pending unix unix

pselect() on Linux does not deliver signals if events are pending


This is a type of resource starvation caused by always checking for active resources in the same order. When resources are always checked in the same order, if the resources checked first are busy enough the resources checked later may never get any attention.

See What is starvation?.

The Linux implementation of pselect() apparently checks file descriptors before checking for signals. The BSD implementation does the opposite.

For what it's worth, the POSIX documentation for pselect() states:

If none of the selected descriptors are ready for the requested operation, the pselect() or select() function shall block until at least one of the requested operations becomes ready, until the timeout occurs, or until interrupted by a signal.

A strict reading of that description requires checking the descriptors first. If any descriptor is active, pselect() will return that instead of failing with errno set to EINTR.

In that case, if the descriptors are so busy that one is always active, the signal processing gets starved.

The BSD implementation likely starves active descriptors if signals come in too fast.

One common solution is to always process all active resources every time a select() call or similar returns. But you can't do that with your current design that mixes signals with descriptors because pselect() doesn't even get to checking for a pending signal if there are active descriptors. As @Shawn mentioned in the comments, you can map signals to file descriptors using signalfd(). Then add the descriptor from signalfd() to the file descriptor set passed to pselect().