|
|
Transport services are inherently asynchronous, with events occurring independently of the actions of the transport user. For example, a user may be sending data over a transport connection when an asynchronous disconnect indication arrives. The user must somehow be informed that the connection has been broken. Both the socket interface and XTI provide an asynchronous mode for managing such events. Asynchronous mode is most useful for applications that expect long delays between events and have other tasks that they can perform in the meantime.
A socket is put into asynchronous mode by calling fcntl(2) and specifying O_NDELAY or O_NONBLOCK. Once in asynchronous mode, all relevant primitives-- send read and so on,-- return EWOULDBLOCK whenever they encounter situations that would have caused them to block if they had been in synchronous mode.
The XTI non-blocking mode is also specified with the O_NDELAY or O_NONBLOCK flag. The O_NDELAY and O_NONBLOCK flags can be used when the transport provider is initially opened with the t_open function, or later with the fcntl call. If the XTI blocking mode is used, these cause the error code EAGAIN to be returned.
There are different levels of asynchronous operation. Specifying O_NDELAY or O_NONBLOCK puts a socket into non-blocking mode. For true asynchronous operation, however, it is also necessary to test for asynchronous events. Socket-based applications normally use select(3C) to test for asynchronous events. XTI-based applications should use poll(2) to test for asynchronous events. select is supported only for compatibility with older applications.
Both XTI and sockets provide mechanisms for asynchronous event notification. Sockets uses fcntl to request that the system issue a SIGIO signal when it becomes possible to perform I/O on a given file descriptor. XTI uses the I_SETSIG ioctl. This causes the system to send the process a SIGPOLL signal when the I/O event specified actually occurs. The XTI mechanism is the more powerful of the two, since it allows users to specify the precise kind of I/O event they want to be signaled on (see the streamio(7) manual page for the possible kinds of events).
A process that issues functions in synchronous mode must still be able to recognize certain asynchronous events immediately and act on them if necessary. Eight such asynchronous events are specified for XTI and cover both connection-oriented and connectionless modes (see the t_look(3xti) manual page). XTI routines that encounter trouble return the special transport error TLOOK. The user can then use the t_look function to identify the event that generated the error. Alternatively, the transport user can use t_look to poll the transport endpoint periodically for asynchronous events. If a sockets function encounters trouble, the primitive will return an errno value directly.