Sunday, November 9, 2014

Unix Prog: Asynchronous I/O

1. Asynchronous I/O

All systems derived from BSD and System V provide some form of asynchronous I/O, using a signal(SIGPOLL in System V; SIGIO in BSD) to notify the process that sth of interest has happened on a descriptor.

Limitation: there is only one signal per process. If we enable more than one descriptor for asynchronous I/O, we cannot tell which descriptor the signal corresponds to when the signal is delivered.

2. System V Asynchronous I/O

It is part of System V OS, and works only with the STREAMS devices and STREAMS pipes. To enable the asynchronous I/O, we have to call ioctl with a second argument of I_SETSIG. The third argument is an integer value formed from one or more of following constants:

 ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/bits/stropts.h  
 ......  
 /* Possible arguments for `I_SETSIG'. */  
 #define S_INPUT     0x0001 /* A message, other than a high-priority  
                   message, has arrived. */  
 #define S_HIPRI     0x0002 /* A high-priority message is present. */  
 #define S_OUTPUT    0x0004 /* The write queue for normal data is no longer  
                   full. */  
 #define S_MSG      0x0008 /* A STREAMS signal message that contains the  
                   SIGPOLL signal reaches the front of the  
                   STREAM head read queue. */  
 #define S_ERROR     0x0010 /* Notification of an error condition. */  
 #define S_HANGUP    0x0020 /* Notification of a hangup. */  
 #define S_RDNORM    0x0040 /* A normal message has arrived. */  
 #define S_WRNORM    S_OUTPUT  
 #define S_RDBAND    0x0080 /* A message with a non-zero priority has  
                   arrived. */  
 #define S_WRBAND    0x0100 /* The write queue for a non-zero priority  
                   band is no longer full. */  
 #define S_BANDURG    0x0200 /* When used in conjunction with S_RDBAND,  
                   SIGURG is generated instead of SIGPOLL when  
                   a priority message reaches the front of the  
                   STREAM head read queue. */  
 ......  
 /* Perform the I/O control operation specified by REQUEST on FD.
    One argument may follow; its presence and type depend on REQUEST.
    Return value depends on REQUEST.  Usually -1 indicates error.  */
 extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;
 ......

If the specified condition (third argument) occurs, the signal SIGPOLL will arrive at process.

Because the default action of SIGPOLL is terminating the process, before calling ioctl, we need to establish the SIGPOLL handler.

3. BSD Asynchronous I/O

BSD OS provides two signals: SIGIO and SIGURG to handle the asynchronous I/O.
SIGIO is the general asynchronous I/O signal, and the latter is used only to notify the process that out-of-band data has arrived on a network connection.

There are 3 steps to enable the asynchronous I/O:
1) Establish the signal handler for SIGIO, by calling either signal or sigaction
2) Set the process ID or process group ID to receive the signal for the descriptor, by calling fcntl with a command of F_SETOWN
3) Enable asynchronous I/O on the descriptor by calling fcntl with a command of F_SETFL to set the O_ASYNC file status flag.

For SIGURG, only step 1 and 2 are needed. SIGURG is generated only for descriptors that refer to network connections that support out-of-band data.

No comments:

Post a Comment