do_poll()

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值