When using nonblocking I/O, applications often exploit the select system call, which relies on a device method when it involves device files. This system call is also used to multiplex input from different sources. In the following discussion, I’m assuming that you understand the use of the select semantics in user space. Note that version 2.1.23 of the kernel introduced the poll system call, thus changing the way the driver method works in order to account for both the system calls.

The implementation of the select system call in Linux 2.0 uses a select_table structure to keep information about all the files (or devices) being waited for. Once again, you’re expected not to look inside the structure (but we’ll do it anyway a little later) and are allowed only to call the functions that act on such a structure.

When the select method discovers that there’s no need to block, it returns 1; when the process should wait, it should ``almost'' go to sleep. In this case, the correct wait queue is added to the select_table structure, and the function returns 0.

The process actually goes to sleep only if no file being selected can accept or return data. This happens in sys_select, within fs/select.c.

The code for the select operation is far easier to write than to describe, and it’s high time to show the implementation used in scull:

int scull_p_select (struct inode *inode, struct file *filp, int mode, select_table *table) { Scull_Pipe *dev = filp->private_data; if (mode == SEL_IN) ...

Get Linux Device Drivers now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.