next up previous
Next: Receiving a poll_diff request Up: Implementing selectable Devices Previous: Implementing selectable Devices

Poll state and the poll_diff callback

FUSD's implementation of selectable devices depends on the concept of poll state. A file descriptor's poll state is a bitmask that describes its current properties--readable, writable, or exception raised. These three states correspond to select(2)'s three fd_sets. FUSD has constants used to describe these states:

These constants can be combined with C's bitwise-or operator. For example, a descriptor that is both readable and writable is expressed as FUSD_NOTIFY_INPUT | FUSD_NOTIFY_OUTPUT. 0 means a file descriptor is not readable, not writable, and not in the exception set.

For a FUSD device to be selectable, its driver must implement a callback called poll_diff. This callback is very different than the others; it is not a ``direct line'' between the client and the driver as is the case with a call such as ioctl. A driver's response to poll_diff is not the return value seen by a client's call to select. When a client tries to select on a set of file descriptors, the kernel collects the responses from all the appropriate callbacks--poll for file descriptors managed by kernel drivers, and poll_diff callbacks those managed by FUSD drivers--and synthesizes all of that information into the return value seen by the client.

FUSD keeps a cache of the poll state it has most recently received from each FUSD device driver, initially assumed to be 0. This state is returned to clients trying to select() on devices managed by those drivers. Under certain conditions, FUSD sends a query to the driver in order to ensure that the kernel's poll state cache is up to date. This query takes the form of a poll_diff callback activation, which is given a single argument: the poll state that FUSD currently has cached. The driver should consult its internal data structures to determine the actual, current poll state (i.e., whether or not buffers have readable data). Then:

In other words, when a driver's poll_diff callback is activated, the kernel is effectively saying to the driver, ``Here is what I think the current poll state of this file descriptor is; let me know when that state changes.'' The driver can either respond immediately (if the kernel's cache is already known to be out of date), or return -FUSD_NOREPLY if no update is immediately necessary. Later, when the poll state changes (for example, if new data arrives that makes a device readable), the driver can used its saved fusd_file_info pointer to send a poll state update to the kernel.

When a FUSD driver sends a poll state update, it might (or might not) have the effect of waking up a client that was blocked in select(2). On the same note, it's worth reiterating that a -FUSD_NOREPLY response to a poll_diff callback does not necessarily block the client--other descriptors in the client's select set might be readable, for example.


next up previous
Next: Receiving a poll_diff request Up: Implementing selectable Devices Previous: Implementing selectable Devices
Jeremy Elson 2003-08-20