set */
int event_fdsz;
fd_set *event_readset_in;
fd_set *event_writeset_in;
fd_set *event_readset_out;
fd_set *event_writeset_out;
struct event **event_r_by_fd;
struct event **event_w_by_fd;
};
selectops也就是实现了eventop。它导出了select的接口。
const struct eventop selectops = {
"select",
select_init,
select_add,
select_del,
select_dispatch,
select_dealloc,
0
};
我们再来看下几个重要的函数(其中省略了一些语句,只介绍重要的一些语句):
struct event_base *
event_base_new(void)
{
......................................
//前面就是一些初始化,最重要的部分是下面的这个for循环。在这里初始化事件驱动引擎。这里eventops是一个eventop数组,里面包含所有事件驱动引擎的接口(就像上面介绍的selectops结构)
for (i = 0; eventops[i] && !base->evbase; i++) {
base->evsel = eventops[i];
///下面调用初始化函数,返回每个事件引擎的全局数据结构
base->evbase = base->evsel->init(base);
}
..................................
/* allocate a single active event queue */
event_base_priority_init(base, 1);
return (base);
}
event_init将event_base_new返回的值付给一个全局的变量current_base
Java代码
struct event_base *
event_init(void)
{
struct event_base *base = event_base_new();
if (base != NULL)
current_base = base;
return (base);
}
event_add加一新的事件到当前事件引擎
int
event_add(struct event *ev, const struct timeval *tv)
{
///取得当前事件的一些有用的数据结构。
struct event_base *base = ev->ev_base;
const struct eventop *evsel = base->evsel;
void *evbase = base->evbase;
int res = 0;
/*
* prepare for timeout insertion further below, if we get a
* failure on any step, we should not change any state.
*/
if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) {
if (min_heap_reserve(&base->timeheap,
1 + min_heap_size(&base->timeheap)) == -1)
return (-1); /* ENOMEM == errno */
}
///这里调用evsel->add来加一事件到当前的事件引擎。
if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) &&
!(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) {
res = evsel->add(evbase, ev);
if (res != -1)
event_queue_insert(base, ev, EVLIST_INSERTED);
}
/*
* we should change the timout state only if the previous event
* addition succeeded.
*/
if (res != -1 && tv != NULL) {
struct timeval now;
/*
* we already reserved memory above for the case where we
* are not replacing an exisiting timeout.
*/
//如果超时就先删除此事件。
if (ev->ev_flags & EVLIST_TIMEOUT)
event_queue_remove(base, ev, EVLIST_TIMEOUT);
/* Check if it is active due to a timeout. Rescheduling
* this timeout before the callback can be executed
* removes it from the active list. */
if ((ev->ev_flags & EVLIST_ACTIVE) &&
(ev->ev_res & EV_TIMEOUT)) {
/* See if we are just active executing this
* event in a lo
|