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));
    }
}

 

转载于:https://www.cnblogs.com/gqtcgq/p/7247108.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值