The meat of the library is a set of alternate system call wrappers. The shows when signals cause system calls to return immediately:
|Signal arrival||normal syscall + null handler||normal syscall + flag handler||normal syscall + ||sigsafe syscall|
|Well before entering kernel||No (signal lost)||Yes||Yes||Yes|
|Right before entering kernel||No (signal lost)||No (signal noted)||Yes||Yes|
|While in kernel||Yes||Yes||Yes||Yes|
|Right after exiting kernel||No (normal return)||No (normal return)||Yes (clobbers syscall return)||No (normal return)|
All sigsafe system calls:
EINTRif a signal arrives right before kernel entry.
It is not possible to create these guarantees with the standard system call wrappers. And they are extremely useful guarantees - you can handle many signals safely without them, but often with a performance penalty or with great difficulty.
sigsafe's goal is to allow every system call to have correct behavior when signals arrive, without compromising speed when signals do not arrive. As most system calls should not be interrupted by a signal, this is a necessary and sufficient condition for saying a signal handling method has good performance.
Another common correct way of handling signals is to set up a pipe for signal handling and write to it in the signal handler. If you're already polling for multiple IO sources, this works well. However, if you're using blocking IO, you have to change to non-blocking and precede all
write() with a
select(). Thus, the system call overhead is doubled in the most common case. For this reason,
sigsafe is often superior to this method.
sigsafe is implemented through a set of system call wrappers implemented in assembly for each platform. The system call wrappers retrieve a "signal received" flag from memory and return
EINTR if it is true shortly before entering the kernel. If a signal is received after this value is retrieved,
sigsafe's signal handler manually adjusts the instruction pointer to force
It sounds like a horrible kludge (and maybe it is), but it works reliably and performs well. But don't take my word for it - verify it yourself with the included race condition checker and benchmarks.
sigsafe is available for the following platforms:
I still intend to port it to:
At which point I will be out of machines to port it to. If you want a platform not listed, you'll have to give me access to such a machine or port it yourself.