poll -- low overhead interface to input/output multiplexing


#include <sys/poll.h>
#include <sys/devpoll.h>


The /dev/poll driver enables an application to efficiently monitor the readiness of an I/O event (read, write or exceptional event). It is similar in functionality to poll(2), but avoids the overhead of this system call. It lets you declare an interest in the file descriptor for which I/O events need to be monitored or revoke an interest or get the list of ready I/O events. Each of these operations is described in detail below:

Creating an interest set

An open(2) of the /dev/poll driver creates a file descriptor representing an empty unique interest set. It does not yet contain any file descriptor for which an application has declared an interest. An application which wants to have disjoint set of file descriptors on which an interest is to be declared must open /dev/poll multiple times.

Declaring or revoking an interest in a file descriptor

A write(2) to the /dev/poll driver with an array of pollfd structure declares an interest in the file descriptor for which I/O events need to be monitored. It also queues events that have already occurred so they can be retrieved using ioctl(2) as described below. An I/O event is immediately enqueued if some data is ready to be read, or if the descriptor is not flow-controlled.

The scope of setting an interest in a descriptor is process-wide. Any thread within a process, can get I/O events when queued.

The definition of pollfd structure is identical to the poll system call.

    struct pollfd {
       int  fd;
       short events;
       short revents;
The fd member specifies the file descriptor of interest. The events member indicates the interested I/O events on the file descriptor. If a pollfd array contains multiple pollfd entries with same fd field, the events member in each pollfd entry is OR'ed.

The set of recommended events for which a process can declare interest include:

   POLLIN	for ready to read interest
   POLLOUT		for ready to write interest
   POLLERR		for receiving exceptions
   POLLREMOVE	 for revoking interest
If the events member contains POLLREMOVE, any interest in the associated fd is revoked. As usual the write call returns the number of bytes written on success; otherwise it returns -1 and set errno to identify the error.

Getting I/O events for the interested set

The DP_POLL ioctl using a file descriptor for /dev/poll obtains a list of I/O events for the file descriptors in which interest was declared. The address of a dvpoll data structure (described below) is passed as the third argument to the ioctl.
    struct dvpoll {
        struct pollfd *dp_fds;
        int dp_nfds;
        int dp_timeout;
The dp_fds member points to an array of struct pollfd with length dp_nfds. If any events are pending for the monitored set, the kernel dequeues, in FIFO order, up to dp_nfds events. It reports these dequeued events in the dp_fds similarly to poll. The revents member gives an event indication for the associated fd member. The set of commonly returned I/O events include:
   POLLIN	ready to read
   POLLOUT	ready to write
   POLLERR	an exception occurred	
If no I/O events are queued for any file descriptor in the interest set, the DP_POLL ioctl waits at least dp_timeout milliseconds for such an event. On a computer where milliseconds timing accuracy is not available, timeout is rounded up to the nearest legal value available on that system. If the value timeout is 0, DP_POLL ioctl returns immediately. If the value of timeout is INFTIM (or -1), the ioctl blocks until at least one event occurs or until the call is interrupted. The DP_POLL ioctl is not affected by the O_NDELAY and O_NONBLOCK flags.

In each valid pollfd entry, the fd member indicates the file descriptor on which the I/O events happened. The events member is the user specified poll events. The revents member contains the events occurred.

Querying a monitored set

DP_ISPOLLED ioctl allows user to query if a file descriptor is already in the monitored set represented by fd. The fd field of the pollfd structure indicates the file descriptor of interest.

Return Values

On success, DP_POLL returns a non-negative value equivalent to the number of I/O events. A value of 0 indicates that the call timed out and no event has been queued. On failure, it returns -1 and sets errno to identify the error.

The DP_ISPOLLED ioctl returns 1 if the file descriptor is in the set. The events field contains the currently polled events. The revents field contains 0.

The ioctl returns 0 if the file descriptor is not in the set. The pollfd structure pointed by pfd is not modified. The ioctl returns a -1 if the call fails and errno is set.


A process does not have permission to access the content cached in /dev/poll.

A signal was caught during the execution of the ioctl function.

The request argument requires a data transfer to or from a buffer pointed to by arg, but arg points to an illegal address.

The request or arg parameter is not valid for this device. or fd is not a supported device type

If an invalid fd is specified.

If memory allocations fail.


close(2), open(2), poll(2), write(2)


Considerations for interface usage:

The /dev/poll API is particularly beneficial to applications which would otherwise repeatedly use select or poll on a large number of file descriptors. Such applications commonly are network applications like the web servers with many connections.

When using the /dev/poll driver, a close(2) of the file descriptor automatically revokes interest from all the monitored poll sets which declared an interest in this file descriptor. It is equivalent to doing a a POLLREMOVE operation on each set in which an interest was declared.

The /dev/poll driver caches a list of polled file descriptors, which are specific to a process. Therefore, the /dev/poll file descriptor of a process will be inherited by its child process, just like any other file descriptor. But the child process will have very limited access through this inherited /dev/poll file descriptor. Any attempt to write or do ioctl by the child process will result in an EACCES error. In effect, the interest declared in a file descriptor is not carried over to its children. The child process should close the inherited /dev/poll file descriptor and open its own if desired.

Declaring interest on special devices has the same behavior as expected for poll or select. It is, however, not recommended that such devices be monitored using /dev/poll.

In contrast to the poll system call which always guarantees delivery of an event if pending, the DP_POLL ioctl call only queues one notification element per-file descriptor for multiple events of the same type. Subsequent events, after the first, are coalesced with an already queued notification element. This may introduce the probability of missing I/O events. For example, an application if does a DP_POLL, followed by a partial read(2) and DP_POLL ioctl again. The second DP_POLL ioctl will sleep, in spite of data being ready because the notification element was consumed during the first call and there were no more queued as only partial read was done. This is a semantic difference between poll or select. To address this, an application must always do non-blocking reads or cache the state of the file descriptor I/O event before issuing another call.

Since the interface coalesces multiple I/O equivalent events for the same descriptor, this can also disrupt the order of I/O events and can possibly starve other descriptors. The application is responsible for balancing the processing of I/O events across multiple file descriptors. In particular, if a POLLIN is posted for a large transfer before small reads for other descriptors, then it may delay or starve handling small requests in spite of using non-blocking reads.

Considerations for multithreaded programming:

In a multi-threaded or multi-process applications, or in an application where the same socket or file is simultaneously open via several descriptors, a race could make the descriptor unready (consume the I/O event) before the application reads the pollfd event bits. The application should use non-blocking operations to read or write these descriptors, even if they appear to be ready.

If an application declares an interest in a file descriptor, then any thread can retrieve the I/O event. The application should use appropriate synchronization primitives to prevent racing threads from attempting to simultaneously get I/O events.

© 2004 The SCO Group, Inc. All rights reserved.
UnixWare 7 Release 7.1.4 - 25 April 2004