图解 epoll 是怎样工作的(2)

电脑杂谈  发布时间:2020-02-05 18:01:00  来源:网络整理

这上面, 又分配了一个struct eppoll_entry结构. 其实它跟struct epitem 结构是一一对应的.

随后就是一些初始化

    init_waitqueue_func_entry(&pwq->wait, ep_poll_callback); //  set func:ep_poll_callback
    pwq->whead = whead;  
    pwq->base = epi;
    add_wait_queue(whead, &pwq->wait) 
    list_add_tail(&pwq->llink, &epi->pwqlist);  
    epi->nwait++; 

这其中相当重要的是设置pwd->wait.func = ep_poll_callback。

现在, struct epitem 和struct eppoll_entry的关系就像下面这种

pointer events none_pointer events_epoll events

图片描述

对于TCP socket, 当收到对端报文后,最初设置的sk->sk_data_ready函数将被调用

void sock_init_data(struct socket *sock, struct sock *sk)
{
    // code omitted...
     sk->sk_data_ready  =   sock_def_readable;
    // code omitted...
}

经过层层调用,最终会调用到 __wake_up_common 这上面会递归挂在socket.wq上的等待队列上的函数

static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
            int nr_exclusive, int wake_flags, void *key)
{
    wait_queue_t *curr, *next;
    list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
        unsigned flags = curr->flags;
        if (curr->func(curr, mode, wake_flags, key) &&
                (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
            break;
    }
} 

于是, 顺着图中的这条黑色轨迹, 就会调用到我们设定的ep_poll_callback,那么接下去就是要让epoll实例才能知有文件早已可读了

图片描述

先从入参中取出当前表项epi和ep

    struct epitem *epi = ep_item_from_wait(wait);
    struct eventpoll *ep = epi->ep; 

再把epi挂到ep的就绪队列

if (!ep_is_linked(&epi->rdllink)) {
        list_add_tail(&epi->rdllink, &ep->rdllist)
    } 

接着唤醒阻塞在(如果有)该epoll实例的用户.

waitqueue_active(&ep->wq) 

谁有也许阻塞在epoll实例的等待队列上呢? 当然就是使用epoll_wait来从epoll实例获取发生了感兴趣事件的的表述符的用户.

epoll_wait会读取到ep_poll()函数.

if (!ep_events_available(ep)) {
        /*
         * We don't have any available event to return to the caller.
         * We need to sleep here, and we will be wake up by
         * ep_poll_callback() when events will become available.
         */
        init_waitqueue_entry(&wait, current);
        __add_wait_queue_exclusive(&ep->wq, &wait); 

如果没有事件,我们就将自己挂在epoll实例的期待队列上之后睡去.....

如果有事件,那么我们还要将事件返回给用户

ep_send_events(ep, events, maxevents) 

the-implementation-of-epoll


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-139730-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...