首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

epoll源码分析-sys_epoll_ctl()函数

2013-01-20 
epoll源码分析---sys_epoll_ctl()函数一、sys_epoll_ctl()函数 源码和注释如下:/** 如果文件类型支持epoll

epoll源码分析---sys_epoll_ctl()函数
一、sys_epoll_ctl()函数 源码和注释如下:

/*  * 如果文件类型支持epoll并且有事件发生,发生的事件通过  * 参数key来传送,参见tcp_prequeue()函数中对wake_up_interruptible_poll()  * 的调用。  * @wait: 调用ep_ptable_queue_proc()加入到文件中的唤醒队列时分配的  * eppoll_entry实例的wait成员的地址  * @mode:该参数在回调函数ep_poll_callback()中没有使用,其值为进程  * 睡眠时的状态  * @sync: 唤醒等待进程的标志  */static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key){    int pwake = 0;    unsigned long flags;    struct epitem *epi = ep_item_from_wait(wait);    struct eventpoll *ep = epi->ep;    spin_lock_irqsave(&ep->lock, flags);    /*     * If the event mask does not contain any poll(2) event, we consider the     * descriptor to be disabled. This condition is likely the effect of the     * EPOLLONESHOT bit that disables the descriptor when an event is received,     * until the next EPOLL_CTL_MOD will be issued.     */    /*     * epi->event.events中存储的是用户空间关心的事件,如果该成员     * 没有包含任何poll事件,则跳转到out_unlock处处理     */    if (!(epi->event.events & ~EP_PRIVATE_BITS))        goto out_unlock;    /*     * Check the events coming with the callback. At this stage, not     * every device reports the events in the "key" parameter of the     * callback. We need to be able to handle both cases here, hence the     * test for "key" != NULL before the event match test.     */    /*     * 如果key不为NULL,也就是值不是0,但是用户关心的     * 事件并没有发生,则跳转到out_unlock处处理。参数key     * 应该不会为0     */    if (key && !((unsigned long) key & epi->event.events))        goto out_unlock;    /*     * If we are trasfering events to userspace, we can hold no locks     * (because we're accessing user memory, and because of linux f_op->poll()     * semantics). All the events that happens during that period of time are     * chained in ep->ovflist and requeued later on.     */    /*      * ep_scan_ready_list()是向用户空间传递事件的处理函数,     * ep_scan_ready_list()函数执行时会将ovflist链表中的元素     * 暂存到一个临时变量中,然后将ovflist成员置为NULL,     * 而EP_UNACTIVE_PTR的定义如下:     * #define EP_UNACTIVE_PTR ((void *) -1L)     * 因此(ep->ovflist != EP_UNACTIVE_PTR)成立时,正在向用户空间     * 传递事件。     * 如果当前正在向用户空间传递事件,则将     * 当前的事件对应的epitem实例加入到ovflist链表中。     */    if (unlikely(ep->ovflist != EP_UNACTIVE_PTR)) {        /*         * 如果epi->next不等于EP_UNACTIVE_PTR,则说明已经         * 添加到ovflist链表中,就不用再添加了         */        if (epi->next == EP_UNACTIVE_PTR) {            epi->next = ep->ovflist;            ep->ovflist = epi;        }        goto out_unlock;    }    /* If this file is already in the ready list we exit soon */    /*     * 如果当前没有在向用户空间传递事件,用户     * 关心的事件已经发生,并且还没有加入到就绪     * 队列中,则将当前的epitem实例加入到就绪队列中。     */    if (!ep_is_linked(&epi->rdllink))        list_add_tail(&epi->rdllink, &ep->rdllist);    /*     * Wake up ( if active ) both the eventpoll wait list and the ->poll()     * wait list.     */    /*     * 唤醒调用epoll_wait()函数时睡眠的进程。     */    if (waitqueue_active(&ep->wq))        wake_up_locked(&ep->wq);    /*     * 唤醒等待eventpoll文件状态就绪的进程     */    if (waitqueue_active(&ep->poll_wait))        pwake++;out_unlock:    spin_unlock_irqrestore(&ep->lock, flags);    /* We have to call this outside the lock */    /*     * 唤醒等待eventpoll文件的状态就绪的进程     */    if (pwake)        ep_poll_safewake(&ep->poll_wait);    return 1;}
该函数主要的功能是将被监视文件的等待事件就绪时,将文件对应的epitem实例添加到就绪队列中,当用户调用epoll_wait()时,内核会将就绪队列中的事件报告给用户

热点排行