event_base回调解析

来源:互联网 发布:八爪盒子 知乎 编辑:程序博客网 时间:2024/04/30 21:38
刨根问底,了解libevent如何实现异步IO。
从后往前研究,先看event_dispatch干啥了
event_dispatch的实现
int  event_base_dispatch(struct event_base *event_base)
{
 return (event_base_loop(event_base, 0));   //唯一的操作是调用event_base_loop
}
继续看,
int
event_base_loop(struct event_base *base, int flags)
{
 const struct eventop *evsel = base->evsel;
。。。。
 while (!done) {
。。。。
res = evsel->dispatch(base, tv_p);   //最关键的部分,既然evsel是base的成员。接着看evsel和dispatch怎么来的,转到event_base_new
 。。。。。
if (N_ACTIVE_CALLBACKS(base))    //检查是否有活动的事件
{
   int n = event_process_active(base);     //处理活动的事件,调用事件回调函数。
   if ((flags & EVLOOP_ONCE)
       && N_ACTIVE_CALLBACKS(base) == 0
       && n != 0)
    done = 1;
  } else if (flags & EVLOOP_NONBLOCK)
   done = 1;
。。。。。

struct event_base  *event_base_new(void)
{
 struct event_base *base = NULL;
 struct event_config *cfg = event_config_new();
 if (cfg)
 {
  base = event_base_new_with_config(cfg);  //调用event_base_new_with_config创建event_base
  event_config_free(cfg);
 }
 return base;
}

struct event_base *
event_base_new_with_config(const struct event_config *cfg)
{
...........
//最关键的部分
 for (i = 0; eventops[i] && !base->evbase; i++)
 {
。。。。。。

  base->evsel = eventops[i];                    //直接给base->evsel赋值为 eventops[i],那么 eventops[i]从哪来呢。

  base->evbase = base->evsel->init(base);   //初始化
 }
。。。。。。。
}
//eventops是全局的静态数组
static const struct eventop *eventops[] = {
#ifdef _EVENT_HAVE_EVENT_PORTS
 &evportops,                                      //这些值都是外部变量,在相应的.c文件有定义
#endif
#ifdef _EVENT_HAVE_WORKING_KQUEUE
 &kqops,
#endif
#ifdef _EVENT_HAVE_EPOLL
 &epollops,                                          //epoll.c有定义,这就转到了epoll模型了
#endif
#ifdef _EVENT_HAVE_DEVPOLL
 &devpollops,
#endif
#ifdef _EVENT_HAVE_POLL
 &pollops,
#endif
#ifdef _EVENT_HAVE_SELECT
 &selectops,
#endif
#ifdef WIN32
 &win32ops,
#endif
 NULL
};

static int
epoll_dispatch(struct event_base *base, struct timeval *tv)
{
。。。。。
res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout);  //等待事件发生
。。。。
evmap_io_active(base, events[i].data.fd, ev | EV_ET);   //把产生的事件添加到活动事件队列
。。。

epoll还没仔细了解过,大概的思路就到这了


0 0
原创粉丝点击