Asynchronous Signals and Wait Termination

An asynchronous signal can alter the operation of a system call or kernel extension by terminating a long wait.

Kernel services such as e_block_thread, e_sleep_thread, and et_wait are affected by signals. The following options are provided when a signal is posted to a thread:

  • Return from the kernel service with a return code indicating that the call was interrupted by a signal
  • Call the longjmpx kernel service to resume execution at a previously saved context in the event of a signal
  • Ignore the signal using the short-wait option, allowing the kernel service to return normally.

The sleep kernel service, provided for compatibility, also supports the PCATCH and SWAKEONSIG options to control the response to a signal during the sleep function.

Previously, the kernel automatically saved context on entry to the system call handler. As a result, any long (interruptible) sleep not specifying the PCATCH option returned control to the saved context when a signal interrupted the wait. The system call handler then set the errno global variable to EINTR and returned a return code of -1 from the system call.

The kernel, however, requires each system call that can directly or indirectly issue a sleep call without the PCATCH option to set up a saved context using the setjmpx kernel service. This is done to avoid overhead for system calls that handle waits terminated by signals. Using the setjmpx service, the system can set up a saved context, which sets the system call return code to a -1 and the ut_error field to EINTR, if a signal interrupts a long wait not specifying return-from-signal.

It is probably faster and more robust to specify return-from-signal on all long waits and use the return code to control the system call return.