libevent源码阅读笔记(二)

     本文主要分析一下event_base相关的数据结构和操作接口。

    1、先看一下event_base结构:

struct event_base {
	const struct eventop *evsel;
	void *evbase;
	int event_count;		/* counts number of total events */
	int event_count_active;	/* counts number of active events */

	int event_gotterm;		/* Set to terminate loop */
	int event_break;		/* Set to terminate loop immediately */

	/* active event management */
	struct event_list **activequeues;
	int nactivequeues;

	/* signal handling info */
	struct evsignal_info sig;

	struct event_list eventqueue;
	struct timeval event_tv;

	struct min_heap timeheap;

	struct timeval tv_cache;
};
 

   相关成员解释如下:

    a).const struct eventop *evsel; 这个成员是对应平台的事件处理函数,该结构的定义如下:

struct eventop {
	const char *name;
	void *(*init)(struct event_base *);
	int (*add)(void *, struct event *);
	int (*del)(void *, struct event *);
	int (*dispatch)(struct event_base *, void *, struct timeval *);
	void (*dealloc)(struct event_base *, void *);
	/* set if we need to reinitialize the event base */
	int need_reinit;
};

     在event_base_new()函数中,会根据对应的平台注册相应的事件处理函数,其中我们在linux平台主要会分析epollops结构中的定义; 该结构用于将libevent的事件处理与select、epoll和kqueue等事件处理关联起来;

  b).void* evbase; 这个为libevent对应的平台事件处理的event base,对于epoll就是epollop结构的指针,具体想了解的可以去阅读epoll相关的书籍;由于需要兼容不同的平台,所以需要存储转化为void* 指针;

  c).int event_count; 是所用的已经注册的事件的总数;

  d).int event_count_active; 当前被激活等待处理的事件;

  e).int event_gotterm; 该变量用于标识是否会退出event_loop,会等到事件处理函数里面才退出;

  f).int event_break; 该变量被设置时,会立即退出event_loop;

  g).struct event_list** activequeques; 是被激活的事件的队列,每个event_loop中,处理该队列中所有的事件,调用对应的回调函数; 这个结构是一个队列数组,数组中的每一项为激活事件队列的头指针,而数组中的index则表示事件的优先级,最低index 的事件队列会最优先被处理;

  h).int nactivequeues; 这个表示active_list的总优先级数;

  i).struct evsignal_info sig; 是用于处理信号的结构,下面会详细分析这个结构;

  j).struct event_list eventqueque; 是所有已注册的事件的队列,每次event_loop都会wait其中所有的事件,并将其中有事件到达的event'添加到active queue中去;

  k).struct timeval event_tv; 这个用于记录当前的事件,用于进行定时相关的处理;

  l).struct min_heap timeheap; 一个小堆,用于管理所有的定时器事件;

 m).struct timeval tv_cache; 没有太大用途,不分析;


  2、struct evsignal_info 结构的分析:

struct evsignal_info {
	struct event ev_signal;
	int ev_signal_pair[2];
	int ev_signal_added;
	volatile sig_atomic_t evsignal_caught;
	struct event_list evsigevents[NSIG];
	sig_atomic_t evsigcaught[NSIG];
#ifdef HAVE_SIGACTION
	struct sigaction **sh_old;
#else
	ev_sighandler_t **sh_old;
#endif
	int sh_old_max;
};

    该结构主要用于进行信号的处理,具体参数的意义说明如下:

    a).struct event_ev_signal; 是用于监听是否有信号发生的事件,这个事件会绑定socketpair[0];

    b).int ev_signal_pair[2]; 是用于处理信号的一对socket pair;

    c).int ev_signal_added; 表明是否已经注册过信号处理的事件,即上面的ev_signal事件是否已经被注册过;

    d).volatile sig_atomic_t evsignal_caught; 类似于一个bool变量,表示是否捕获到信号的发生;

    e).struct event_list evsigevents[NSIG]; 是注册的对应信号的event, 数组下标为产生的信号,每个数组都是一个event_list,其中是该信号所有已经注册的event,从这个地方我们可以看到,一个signal是可以注册多个处理函数的;

    f).sig_atomic_t evsigcaught[NSIG]; 是一个数组,其中每个slot对应一个信号,用于表示是否产生了该信号;

   g).下面的old相关的都是用于在循环结束时恢复老的信号处理函数;


    在下面的文章中,将从处理流程的角度分别介绍相关事件处理的流程。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值