您的位置:首页 > 其它

do_poll()

2015-12-11 13:16 267 查看
static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
{
unsigned int mask;
int fd;
/**
mask的初始值为0.
*/
mask = 0;
fd = pollfd->fd;
if (fd >= 0) {
int fput_needed;
struct file * file;
/**
从当前进程描述符数组中依据fd为索引值 取出相应的file对象
数组中的表项是一个指针,指向了一个已经打开的文件
struct files_struct {

atomic_t count;
...
int next_fd;
...
struct file * fd_array[NR_OPEN_DEFAULT];
};
*/
file = fget_light(fd, &fput_needed);
mask = POLLNVAL;
if (file != NULL) {
mask = DEFAULT_POLLMASK;
if (file->f_op && file->f_op->poll) {
if (pwait)
pwait->key = pollfd->events |POLLERR | POLLHUP;
/**
调用驱动中的poll()函数。
如果返回值不为0,那么会让do_poll()函数中的count++。
所以可以看出:驱动中的poll()函数的返回值 决定了进程是不是被阻塞
*/
mask = file->f_op->poll(file, pwait);
}
/**
pollfd->events : 请求检测的事件
*/
mask &= pollfd->events | POLLERR | POLLHUP;
/**
更新文件的引用计数
*/
fput_light(file, fput_needed);
}
}
/**
pollfd->revents : 被检测之后返回的事件
*/
pollfd->revents = mask;

return mask;
}

static int do_poll(unsigned int nfds,  struct poll_list *list,struct poll_wqueues *wait, struct timespec *end_time)
{
....
for (;;) {
...
/**
遍历多个文件。
这是poll的一个缺陷吧,不论活跃的文件描述符的多少,它都要遍历整个集合
*/
for (; pfd != pfd_end; pfd++)
{
/**
在上面的do_pollfd()函数中如果驱动的poll()函数不返回0,那么
count++,进程就不会被阻塞。
*/
if (do_pollfd(pfd, pt))
{
/**
count++.
下面的代码有根据count的值来决定是不是要进程休眠的。
*/
count++;
pt->_qproc = NULL;
}
}
if (!count)
{
count = wait->error;
/**
检查当前进程是否有信号要处理
*/
if (signal_pending(current))
{
count = -EINTR;
}
}
/**
如果count为0,则不会跳出循环,会进入下面的函数休眠
否则,就跳出循环
*/
if (count || timed_out)
{
break;
`           }

....
/**
让进程休眠
*/
if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack))
{
timed_out = 1;
}
}
return count;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: