• 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(七)信号事件监听

     

  • 相关阅读:
    【泛型方法】
    【为什么使用泛型?】
    【泛型类】
    【泛型:ArrayListDemo】
    【泛型概述】
    【Collections:集合工具类:扑克游戏】
    【Collections:集合工具类:自然排序和比较器排序】
    Navicat for MYSQL 断网时本地连接无法打开,2005错误
    Navicat for MYSQL 数据库手动同步方法
    spring redis @Cacheable注解使用部分错误及无效原因
  • 原文地址:https://www.cnblogs.com/gattaca/p/7682923.html
Copyright © 2020-2023  润新知