欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

libevent(二)event_assign

程序员文章站 2022-06-01 09:20:42
...

信号或套接字都可以作为一个event的监听对象,并且一个信号或套接字可同时加入到多个event。
结构体struct event_base

结构体struct event:

struct event {
    struct event_callback ev_evcallback;

    /* for managing timeouts */
    union {
        TAILQ_ENTRY(event) ev_next_with_common_timeout;
        size_t min_heap_idx;
    } ev_timeout_pos;//管理定时器事件
    evutil_socket_t ev_fd;//监听对象套接字或信号

    struct event_base *ev_base;//所属event_base

    union {13
        /* used for io events */
        struct {
            LIST_ENTRY (event) ev_io_next;
            struct timeval ev_timeout;
        } ev_io;//套接字对象


        /* used by signal events */
        struct {
            LIST_ENTRY (event) ev_signal_next;
            short ev_ncalls;
            /* Allows deletes in callback */
            short *ev_pncalls;
        } ev_signal;//信号对象
    } ev_;


    short ev_events;//监听事件类型EV_READ...
    short ev_res;  //**事件类型     /* result passed to event callback */
    struct timeval ev_timeout;//定时器超时值
};

struct event_callback {
    TAILQ_ENTRY(event_callback) evcb_active_next;//**队列
    short evcb_flags;
    ev_uint8_t evcb_pri;//event的优先级    /* smaller numbers are higher priority */
    ev_uint8_t evcb_closure;
    /* allows us to adopt for different types of events */
        union {
        void (*evcb_callback)(evutil_socket_t, short, void *);
        void (*evcb_selfcb)(struct event_callback *, void *);
        void (*evcb_evfinalize)(struct event *, void *);
        void (*evcb_cbfinalize)(struct event_callback *, void *);
    } evcb_cb_union;//回调函数
    void *evcb_arg;//回调函数参数
};

创建event

struct event *
event_new(struct event_base *base, evutil_socket_t fd, short events, void (*             
cb)(evutil_socket_t, short, void *), void *arg)
{
    struct event *ev;
    ev = mm_malloc(sizeof(struct event));
    if (ev == NULL)
        return (NULL);
    if (event_assign(ev, base, fd, events, cb, arg) < 0) {
        mm_free(ev);
        return (NULL);
    }


    return (ev);
}

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;//current_base为全局指针,被初始化为NULL
    if (arg == &event_self_cbarg_ptr_)//event_self_cbarg_ptr_为全局指针,初始化为NULL
        arg = ev;


    if (!(events & EV_SIGNAL))
        event_debug_assert_socket_nonblocking_(fd);//如果event不是信号,判断套接字是否为非阻塞
    event_debug_assert_not_added_(ev);//判断此event是否是没有被"add"


    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|EV_CLOSED)) != 0) {
            event_warnx("%s: EV_SIGNAL is not compatible with "
                "EV_READ, EV_WRITE or EV_CLOSED", __func__);
            return -1;
        }
        ev->ev_closure = EV_CLOSURE_EVENT_SIGNAL;//如果event标志是信号,则判断是否还有EV_READ等标志,有就会出错,最后初始化ev_closure。
    } else {
        if (events & EV_PERSIST) {
            evutil_timerclear(&ev->ev_io_timeout);
            ev->ev_closure = EV_CLOSURE_EVENT_PERSIST;
       } else {
            ev->ev_closure = EV_CLOSURE_EVENT;
        }
    }//如果event为套接字(文件描述符)标志,则判断event是否设置EV_PERSIST标志,并设置ev_closure为对应宏


    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);//加入event到全局队列global_debug_map


    return 0;
}

event_assign初始化中,会将ev_flag初始化为EVLIST_INIT。

event2/event_struct.h

#define EVLIST_TIMEOUT      0x01//event从属于定时器队列或者时间堆
#define EVLIST_INSERTED     0x02//event从属于注册队列
#define EVLIST_SIGNAL       0x04//没有使用
#define EVLIST_ACTIVE       0x08//event从属于活动队列
#define EVLIST_INTERNAL     0x10//该event是内部使用的。信号处理时有用到
#define EVLIST_ACTIVE_LATER 0x20
#define EVLIST_FINALIZING   0x40
#define EVLIST_INIT     0x80//event已经被初始化了
    
#define EVLIST_ALL          0xff//所有标志。这个不能取
相关标签: libevent学习