libevent(三)event_base
阿新 • • 發佈:2017-05-23
16px pat alloc mage signal .com events vba alt
libevent能夠處理三種事件: I/O、信號、定時器。
涉及兩個數據結構:
event,表示一個事件
event_base,管理所有事件
本文主要介紹event_base,結構如下:
struct event_base { const struct eventop *evsel; // backend void *evbase; const struct eventop *evsigsel; struct evsig_info sig; int event_count; // 事件總數int event_count_active; // 活躍事件總數 struct event_list eventqueue; // 存儲所有事件 struct event_io_map io; // 存儲I/O事件 struct event_signal_map sigmap; // 存儲信號事件 struct min_heap timeheap; // 存儲定時器事件 struct event_list *activequeues; // 存儲激活事件 intnactivequeues; // 激活隊列個數 struct timeval event_tv; struct timeval tv_cache; void *th_base_lock; int is_notify_pending; evutil_socket_t th_notify_fd[2]; struct event th_notify; int (*th_notify_fn)(struct event_base *base); ... };
evsel主要描述libevent的底層實現機制,linux系統對應epoll。
/** Structure to define the backend of a given event_base. */ struct eventop { const char *name; void *(*init)(struct event_base *); int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo); int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo); int (*dispatch)(struct event_base *, struct timeval *); void (*dealloc)(struct event_base *); int need_reinit; enum event_method_feature features; size_t fdinfo_len; }; const struct eventop epollops = { "epoll", epoll_init, epoll_nochangelist_add, epoll_nochangelist_del, epoll_dispatch, epoll_dealloc, 1, /* need reinit */ EV_FEATURE_ET|EV_FEATURE_O1, 0 };
event_list是一個雙向鏈表,min_heap是一個小根堆,而event_io_map結構有點復雜。
在linux系統,event_io_map就是event_signal_map,結構如下:
struct event_signal_map { void **entries; /* An array of evmap_io * or of evmap_signal */ int nentries; }; struct evmap_io { struct event_list events; ev_uint16_t nread; ev_uint16_t nwrite; }; struct evmap_signal { struct event_list events; };
一圖勝千言:
可以看出,一個event_signal_map對應多個雙向鏈表。同一個fd或signal的事件位於同一個鏈表中。
libevent(三)event_base