Linux设备驱动程序第三版学习(7)- 高级字符驱动程序操作(续2)- poll/select

时间:2021-04-06 00:05:30

 第六章:高级字符驱动程序操作(续2)
以下为第三部分:poll/select系统调用

poll方法执行了两个任务:
第一项任务:调用poll_wait方法向poll_table结构添加一个等待队列
第二项任务:返回一个位掩码(mask),该位掩码秒数了哪个操作可以立即执行而不会被阻塞。

对于位掩码,定义在asm-generic/poll.h中,为了以后方便查阅,记录如下:
   
看一下scullpipe中的poll实现:


===============================================================================================
总结:当应用程序调用poll或select时就会知道接下来要进行的操作是否会阻塞。
通常将poll和read/write一起使用,综合分析前面的read和write方法可以知道从设备读取数据和向设备写入数据的流程。
从设备读取数据:
*如果输入缓冲区有数据,那么及时就绪的数据比程序所请求的少,并且驱动程序保证剩下的数据马上就能到达,read调用仍然应该以难以察觉的延迟立即返回。read甚至可以一直返回比所请求数目少的数据(至少返回一个字节)。
*如果输入缓冲区没有数据,那么默认情况read必须阻塞等待,直到至少一个字节到达。而如果设置了O_NONBLOCK标志,则read不阻塞,应立即返回,返回值是-EAGAIN。这时poll必须报告设备不可读,直到至少一个字节到达。一旦缓冲区有了数据,就回到了上一种情况
*如果已经到达文件为,则read应该立即返回0,无论是否阻塞。此时poll应该报告POLLHUP(挂起)

向设备写数据:
*如果输出缓冲区有空间,则write应该无延迟地立即返回。它可以接收比请求少的数据(知道接收一个字节)。这时poll报告设备可写。
*如果输出缓冲区已满,那么默认情况write被阻塞直到有空间。如果设置了O_NONBLOCK标志,则write不阻塞,应立即返回,返回值是-EAGAIN。这时poll报告文件不可写。另一方面,如果设备不能再接收任何数据,则write返回-ENOSPC(no space left on device 设备无可用空间),而不管是否阻塞。
*永远不要让write在返回前等待数据的传输结束,即使O_NONBLOCK被清除。因为应用程序用select来检查write是否会阻塞,如果poll报告设备可以写入,则write就不会被阻塞。驱动程序可以实现fsync方法来保证输出缓冲区的数据确实已经被传送出去了。

===============================================================================================