libevent(五)event

libevent使用struct event来表示一个事件。

#define evutil_socket_t int
#define ev_uint8_t unsigned char
#define ev_io_timeout    _ev.ev_io.ev_timeout       // 存储绝对时间

struct event {
    evutil_socket_t ev_fd;      // 事件相关描述符
    short ev_events;            // 事件类型
    short ev_flags;             // 事件状态
    ev_uint8_t ev_closure;      // 事件结束类型
    ev_uint8_t ev_pri;          // 事件优先级,越小优先级越高
    struct timeval ev_timeout;  // 存储相对时间
    union {
        /* used for io events */
        struct {
            TAILQ_ENTRY(event) ev_io_next;
            struct timeval ev_timeout;
        } ev_io;
        
        /* used by signal events */
        struct {
            TAILQ_ENTRY(event) ev_signal_next;
            short ev_ncalls;
            /* Allows deletes in callback */
            short *ev_pncalls;
        } ev_signal;
    } _ev;
    
    /* for managing timeouts */
    union {
        TAILQ_ENTRY(event) ev_next_with_common_timeout;
        int min_heap_idx;                                       // 事件在最小堆中的index
    } ev_timeout_pos;
    
    
    void (*ev_callback)(evutil_socket_t, short, void *arg);     // 事件回调函数
    void *ev_arg;                                               // 存储事件回调函数参数arg
    
    struct event_base *ev_base;
    
    ...
};

具体字段含义不再细说,可参考event_assign进行理解。

int
event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg)
{
    if (!base)
        base = current_base;

    _event_debug_assert_not_added(ev);

    ev->ev_base = base;

    ev->ev_callback = callback;
    ev->ev_arg = arg;
    ev->ev_fd = fd;
    ev->ev_events = events;
    ev->ev_res = 0;
    ev->ev_flags = EVLIST_INIT;
    ev->ev_ncalls = 0;
    ev->ev_pncalls = NULL;

    if (events & EV_SIGNAL) {
        if ((events & (EV_READ|EV_WRITE)) != 0) {
            event_warnx("%s: EV_SIGNAL is not compatible with "
                "EV_READ or EV_WRITE", __func__);
            return -1;
        }
        ev->ev_closure = EV_CLOSURE_SIGNAL;
    } else {
        if (events & EV_PERSIST) {
            evutil_timerclear(&ev->ev_io_timeout);
            ev->ev_closure = EV_CLOSURE_PERSIST;
        } else {
            ev->ev_closure = EV_CLOSURE_NONE;
        }
    }

    min_heap_elem_init(ev);

    if (base != NULL) {
        /* by default, we put new events into the middle priority */
        ev->ev_pri = base->nactivequeues / 2;
    }

    _event_debug_note_setup(ev);

    return 0;
}
View Code

ev_events事件类型

/**
 * @name event flags
 *
 * Flags to pass to event_new(), event_assign(), event_pending(), and
 * anything else with an argument of the form "short events"
 */
/**@{*/
/** Indicates that a timeout has occurred.  It's not necessary to pass
 * this flag to event_for new()/event_assign() to get a timeout. */
#define EV_TIMEOUT    0x01
/** Wait for a socket or FD to become readable */
#define EV_READ        0x02
/** Wait for a socket or FD to become writeable */
#define EV_WRITE    0x04
/** Wait for a POSIX signal to be raised*/
#define EV_SIGNAL    0x08
/**
 * Persistent event: won't get removed automatically when activated.
 *
 * When a persistent event with a timeout becomes activated, its timeout
 * is reset to 0.
 */
#define EV_PERSIST    0x10
/** Select edge-triggered behavior, if supported by the backend. */
#define EV_ET       0x20
/**@}*/

对于定时器事件,不需要设置EV_TIMEOUT。

ev_flags,事件状态

#define EVLIST_TIMEOUT    0x01  // 事件位于最小堆
#define EVLIST_INSERTED   0x02  // 事件位于总事件队列
#define EVLIST_SIGNAL     0x04  // 
#define EVLIST_ACTIVE     0x08  // 事件位于激活队列
#define EVLIST_INTERNAL   0x10
#define EVLIST_INIT       0x80  // 事件初始状态

event_add流程

 信号事件的event_add过程有点复杂,可以参考

libevent(七)信号事件监听

 

posted @ 2017-10-17 17:30  Sawyer Ford  阅读(375)  评论(0编辑  收藏  举报