zoukankan      html  css  js  c++  java
  • Libev源码分析10:libev中poll的用例

             在Libev中,使用poll作为backend时,涉及到下面几种数据结构:

    int *pollidxs;
    int pollidxmax;
    
    struct pollfd *polls;
    int pollmax;
    int pollcnt;

             polls就是struct pollfd结构的数组,pollmax是该数组的实际大小,pollcnt表示该数组中,有效结构的个数。也就是监控的描述符个数。

             pollidxs是整型数组,以描述符fd为下标,pollidxs[fd]表示该fd对应的struct pollfd结构在polls中的下标。pollidxs[fd]== -1表示该描述符无效。pollidxmax表示pollidxs数组的大小。

            增加pollidxs这种结构,主要是为了在取消监控fd时,能够快速定位polls,从而加快取消速度。

             因此,上面的结构满足等式:

    idx = pollidxs [fd];
    polls[idx].fd == fd;
    

    1:poll_init

             以poll为backend时,相关的函数和数据结构初始化。代码如下:

    backend_mintime = 1e-3;
    backend_modify  = poll_modify;
    backend_poll    = poll_poll;
    
    pollidxs = 0; pollidxmax = 0;
    polls    = 0; pollmax    = 0; pollcnt = 0;
    

    2:poll_modify

             主要设置相关fd的struct pollfd结构,完整代码如下:

    static void poll_modify (struct ev_loop *loop, int fd, int oev, int nev)
    {
        int idx;
    
        if (oev == nev)
            return;
        array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init);
    
        idx = pollidxs [fd];
    
        if (idx < 0) /* need to allocate a new pollfd */
        {
            pollidxs [fd] = idx = pollcnt++;
            array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2);
            polls [idx].fd = fd;
        }
    
        assert (polls [idx].fd == fd);
    
        if (nev)
            polls [idx].events = (nev & EV_READ ? POLLIN : 0) | (nev & EV_WRITE ? POLLOUT : 0);
        else /* remove pollfd */
        {
            pollidxs [fd] = -1;
            if (expect_true (idx < --pollcnt))
            {
                polls [idx] = polls [pollcnt];
                pollidxs [polls [idx].fd] = idx;
            }
        }
    }
    

             代码还是比较好理解的,首先取得pollidxs [fd]的值,也就是该fd对应的struct pollfd结构在polls数组中的下标。如果该值为-1,说明该fd是第一次加入监控,相应的设置pollidxs[fd]和polls [idx]。

             如果env不为0,则设置struct pollfd结构中的events,如果它为0,表示要去除该fd的监控,首先置pollidxs [fd] = -1表示该fd无效,然后去除相应的struct pollfd结构,首先--pollcnt,如果idx == pollcnt,则直接退出即可,否则,将polls数组中的最后一个元素置换到polls[idx]中,并设置相应的pollidxs元素。

     

    3:poll_poll

             主要调用poll函数,等待描述符事件的触发。主要是对触发的描述符和事件调用fd_event。主要代码如下:

    res = poll (polls, pollcnt, timeout * 1e3);
    if (expect_false (res < 0))
    {
        ...
    }
    else
    for (p = polls; res; ++p)
    {
        assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt));
    
        if (expect_false (p->revents)) /* this expect is debatable */
        {
            --res;
            if (expect_false (p->revents & POLLNVAL))
                fd_kill (EV_A_ p->fd);
            else
                fd_event (EV_A_  p->fd, (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
                     | (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0));
        }
    }
    

     

  • 相关阅读:
    Leetcode645.Set Mismatch错误的集合
    Leetcode622.Design Circular Queue设计循环队列
    Leetcode628.Maximum Product of Three Numbers三个数的最大乘积
    Leetcode633.Sum of Square Numbers平方数之和
    Leetcode617.Merge Two Binary Trees合并二叉树
    Leetcode606.Construct String from Binary Tree根据二叉树创建字符串
    SQL Sever实验二 交互式 SQL
    [bzoj2124]等差子序列_线段树_hash
    [bzoj4084][Sdoi2015]双旋转字符串_hash
    [bzoj1708][Usaco2007 Oct]Money奶牛的硬币_动态规划_背包dp
  • 原文地址:https://www.cnblogs.com/gqtcgq/p/7247108.html
Copyright © 2011-2022 走看看