1352 Chapter 63
Signal-driven I/O works for stream sockets in both the UNIX and the Internet
domains. A signal is generated in the following circumstances:
z A new connection is received on a listening socket.
z A TCP connect() request completes; that is, the active end of a TCP connection
entered the ESTABLISHED state, as shown in Figure 61-5 (page 1272). The
analogous condition is not signaled for UNIX domain sockets.
z New input is received on the socket (even if there was already unread input
available).
z The peer closes its writing half of the connection using shutdown(), or closes its
socket altogether using close().
z Output is possible on the socket (e.g., space has become available in the socket
send buffer).
z An asynchronous error occurs on the socket.
inotify file descriptors
A signal is generated when the inotify file descriptor becomes readable—that is,
when an event occurs for one of the files monitored by the inotify file descriptor.
63.3.2 Refining the Use of Signal-Driven I/O
In applications that need to simultaneously monitor very large numbers (i.e., thou-
sands) of file descriptors—for example, certain types of network servers—signal-
driven I/O can provide significant performance advantages by comparison with
select() and poll(). Signal-driven I/O offers superior performance because the kernel
“remembers” the list of file descriptors to be monitored, and signals the program only
when I/O events actually occur on those descriptors. As a result, the performance of
a program employing signal-driven I/O scales according to the number of I/O
events that occur, rather than the number of file descriptors being monitored.
To take full advantage of signal-driven I/O, we must perform two steps:
z Employ a Linux-specific fcntl() operation, F_SETSIG, to specify a realtime signal
that should be delivered instead of SIGIO when I/O is possible on a file descriptor.
z Specify the SA_SIGINFO flag when using sigaction() to establish the handler for the
realtime signal employed in the previous step (see Section 21.4).
The fcntl() F_SETSIG operation specifies an alternative signal that should be delivered
instead of SIGIO when I/O is possible on a file descriptor:
if (fcntl(fd, F_SETSIG, sig) == -1)
errExit("fcntl");
The F_GETSIG operation performs the converse of F_SETSIG, retrieving the signal cur-
rently set for a file descriptor:
sig = fcntl(fd, F_GETSIG);
if (sig == -1)
errExit("fcntl");