struct event {
TAILQ_ENTRY (event) ev_next;
TAILQ_ENTRY (event) ev_active_next;
TAILQ_ENTRY (event) ev_signal_next;
unsigned int min_heap_idx; /* for managing timeouts */
struct event_base *ev_base;
int ev_fd;
short ev_events;
short ev_ncalls;
short *ev_pncalls; /* Allows deletes in callback */
struct timeval ev_timeout;
int ev_pri; /* smaller numbers are higher priority */
void (*ev_callback)(int, short, void *arg);
void *ev_arg;
int ev_res; /* result passed to event callback */
int ev_flags;
};
在这里我解释一下:
1.第一二三个参数都是双链表结构,第一个的是一个event双链表 第二个是激活事件的双链表,第三个是一个信号事件的双链表;第三个是时间最小堆;
2.第四个参数这个需要强调一下;这里是event_base*为啥不是event_base呢?是因为如果是event_base结构体的话,每个event都需要绑定一个event_base结构,但是每个event需要使用的event_base都是一样的,这里使用的event_base是很明智的,这里可以省很多内存;每个event都指向一个event_base对象,
3.这里有一个ev_fd这里对I/O来说是文件描述符,或者直接说就是一个socket 但是对Signal来说是一个信号
4.ev_event这个是event的类型 event的类型有以下几种;
#define EV_TIMEOUT 0x01
#define EV_READ 0x02
#define EV_WRITE 0x04
#define EV_SIGNAL 0x08
#define EV_PERSIST 0x10 /* Persistant event */
注意这里的Event类型只有四种最后一种是辅助类型
第一个是定时Event
第二三个是I/O Event
第四个是信号 Event
第五个是永久Event
ev_ncalls:事件就绪执行时,调用ev_callback的次数,通常为1;
ev_pncalls:指针,通常指向ev_ncalls或者为NULL;//这里我不清楚设置这个参数的原因
ev_callback这里是调用Event处理是调用的回调函数;
ev_pri这里是设置Event的优先级;
void* ev_arg这里处理的是回调函数的参数;
ev_res:记录了当前激活事件的类型;//这个很有用纪录激活事件的类型
最后一个参数eb_flags:libevent用于标记event信息,表明其当前的状态:
#define EVLIST_TIMEOUT 0x01 // event在time堆中
#define EVLIST_INSERTED 0x02 // event在已注册事件链表中
#define EVLIST_SIGNAL 0x04 // 未见使用
#define EVLIST_ACTIVE 0x08 // event在激活链表中
#define EVLIST_INTERNAL 0x10 // 内部使用标记
#define EVLIST_INIT 0x80 // event已被初始化
写到这里我感觉 这些参数设置的真细致,感觉libevent真的太优秀了 下片博文再说一个简单的strlcpy这个函数,设计的感觉very good