首页 > 代码库 > libevent(三)event_base

libevent(三)event_base

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;    // 存储激活事件
    int nactivequeues;                  // 激活队列个数
    
    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