select & poll functions

6.3 select Function

This function allows the process to instruct the kernel to wait for any one of multiple events to occur and to wake up the process only when one or more of these events occurs or when a specified amount of time has passed.
As an example, we can call select and tell the kernel to return only when:
  • Any of the descriptors in the set {1, 4, 5} are ready for reading
  • Any of the descriptors in the set {2, 7} are ready for writing
  • Any of the descriptors in the set {1, 4} have an exception condition pending
  • 10.2 seconds have elapsed
That is, we tell the kernel what descriptors we are interested in (for reading, writing, or an exception condition) and how long to wait. The descriptors in which we are interested are not restricted to sockets; any descriptor can be tested using select.
Berkeley-derived implementations have always allowed I/O multiplexing with any descriptor. SVR3 originally limited I/O multiplexing to descriptors that were STREAMS devices (Chapter 31), but this limitation was removed with SVR4.


#include <sys/select.h>
#include <sys/time.h>
int select(int maxfdp1fd_set *readsetfd_set *writesetfd_set *exceptsetconst struct timeval *timeout);


Figure 6.7. Summary of conditions that cause a socket to be ready for select.
graphics/06fig07.gif

6.10 poll Function

The poll function originated with SVR3 and was originally limited to STREAMS devices (Chapter 31). SVR4 removed this limitation, allowing poll to work with any descriptor. pollprovides functionality that is similar to select, but poll provides additional information when dealing with STREAMS devices.
#include <poll.h>
int poll (struct pollfd *fdarrayunsigned long nfdsint timeout);
Returns: count of ready descriptors, 0 on timeout, –1 on error
The first argument is a pointer to the first element of an array of structures. Each element of the array is a pollfd structure that specifies the conditions to be tested for a given descriptor, fd.
struct pollfd {
  int     fd;       /* descriptor to check */
  short   events;   /* events of interest on fd */
  short   revents;  /* events that occurred on fd */
};
The conditions to be tested are specified by the events member, and the function returns the status for that descriptor in the corresponding revents member. (Having two variables per descriptor, one a value and one a result, avoids value-result arguments. Recall that the middle three arguments for select are value-result.) Each of these two members is composed of one or more bits that specify a certain condition. Figure 6.23 shows the constants used to specify the events flag and to test the revents flag against.
Figure 6.23. Input events and returned revents for poll.
graphics/06fig23.gif