8.4.1 Signal Control Blocks
If the underlying kernel provides a signal facility, it creates the signal control block as part of the task control block as shown in Figure 8.11.

Figure 8.11: Signal control block.
The signal control block maintains a set of signals-the wanted signals-which the task is prepared to handle. When a task is prepared to handle a signal, it is often said, “the task is
Signals can be ignored, made pending, processed (handled), or blocked.
The signals to be ignored by the task are maintained in the ignored signals set. Any signal in this set does not interrupt the task.
Other signals can arrive while the task is in the midst of processing another signal. The additional signal arrivals are kept in the pending signals set. The signals in this set are raised to the task as soon as the task completes processing the previous signal. The pending signals set is a subset of the wanted signals set.
To process a particular signal, either the task-supplied signal handler can be used for signal processing or the default handler supplied by the underlying kernel can be used to process it. It is also possible for the task to process the signal first and then pass it on for additional processing by the default handler.
A fourth kind of response to a signal is possible. In this case, a task does not ignore the signal but blocks the signal from delivery during certain stages of the task’s execution when it is critical that the task not be interrupted.
Blocking a signal is similar to the concept of entering a critical section, discussed in Chapter 15. The task can instruct the kernel to block certain signals by setting the blocked signals set. The kernel does not deliver any signal from this set until that signal is cleared from the set.
8.4.2 Typical Signal Operations
Signal operations are available, as shown in Table 8.6.
Table 8.6: Signal operations.
Operation | Description |
---|---|
Catch | Installs a signal handler |
Release | Removes a previously installed handler |
Send | Sends a signal to another task |
Ignore | Prevents a signal from being delivered |
Block | Blocks a set of signal from being delivered |
Unblock | Unblocks the signals so they can be delivered |
A task can catch a signal after the task has specified a handler (ASR) for the signal. The catch operation installs a handler for a particular signal. The kernel interrupts the task’s execution upon the arrival of the signal, and the handler is invoked. The task can install the kernel-supplied default handler, the
After a handler has been installed for a particular signal, the handler is invoked if the same type of signal is received by any task, not just the one that installed it. In addition, any task can change the handler installed for a particular signal. Therefore, it is good practice for a task to save the previously installed handler before installing its own and then to restore that handler after it finishes catching the handler’s corresponding signal.
Figure 8.12 shows the signal vector table, which the kernel maintains. Each element in the vector table is a pointer or offset to an ASR. For signals that don’t have handlers assigned, the corresponding elements in the vector table are NULL. The example shows the table after three catch operations have been performed. Each catch operation installs one ASR, by writing a pointer or offset to the ASR into an element of the vector table.

Figure 8.12: The catch operation.
The release operation de-installs a signal handler. It is good practice for a task to restore the previously installed signal handler after calling release.
The send operation allows one task to send a signal to another task. Signals are usually associated with hardware events that occur during execution of a task, such as generation of an unaligned memory address or a floating-point exception. Such signals are generated automatically when their corresponding events occur. The send operation, by contrast, enables a task to explicitly generate a signal.
The ignore operation allows a task to instruct the kernel that a particular set of signals should never be delivered to that task. Some signals, however, cannot be ignored; when these signals are generated, the kernel calls the default handler.
The block operation does not cause signals to be ignored but temporarily prevents them from being delivered to a task. The block operation protects critical sections of code from interruption. Another reason to block a signal is to prevent conflict when the signal handler is already executing and is in the midst of processing the same signal. A signal remains pending while it’s blocked.
The unblock operation allows a previously blocked signal to pass. The signal is delivered immediately if it is already pending.