码迷,mamicode.com
首页 > 其他好文 > 详细

Libevent 事件生成

时间:2017-11-09 17:25:30      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:elf   als   参数   eve   head   vma   should   variables   hint   

事件堆实例生成:

struct event_base *
event_base_new(void)
{
    struct event_base *base = NULL;
    struct event_config *cfg = event_config_new();
    if (cfg) {
        base = event_base_new_with_config(cfg);
        event_config_free(cfg);
    }
    return base;
}
event_config 结构如下
struct event_config {
    TAILQ_HEAD(event_configq, event_config_entry) entries;

    int n_cpus_hint;
    struct timeval max_dispatch_interval;
    int max_dispatch_callbacks;
    int limit_callbacks_after_prio;
    enum event_method_feature require_features;
    enum event_base_config_flag flags;
};

struct event_base *
event_base_new_with_config(const struct event_config *cfg)
{
    int i;
    struct event_base *base;

    if ((base = mm_calloc(1, sizeof(struct event_base))) == NULL) {
        event_warn("%s: calloc", __func__);
        return NULL;
    }

    if (cfg)
        base->flags = cfg->flags;

    should_check_environment =
        !(cfg && (cfg->flags & EVENT_BASE_FLAG_IGNORE_ENV));

    {
        struct timeval tmp;
        int precise_time =
            cfg && (cfg->flags & EVENT_BASE_FLAG_PRECISE_TIMER);
        int flags;
        if (should_check_environment && !precise_time) {
            precise_time = evutil_getenv_("EVENT_PRECISE_TIMER") != NULL;
            base->flags |= EVENT_BASE_FLAG_PRECISE_TIMER;
        }
        flags = precise_time ? EV_MONOT_PRECISE : 0;
        evutil_configure_monotonic_time_(&base->monotonic_timer, flags);

        gettime(base, &tmp);
    }
  //初始化小根堆
    min_heap_ctor_(&base->timeheap);

    base->sig.ev_signal_pair[0] = -1;
    base->sig.ev_signal_pair[1] = -1;
    base->th_notify_fd[0] = -1;
    base->th_notify_fd[1] = -1;

    TAILQ_INIT(&base->active_later_queue);
    //初始化io singal哈系表
    evmap_io_initmap_(&base->io);
    evmap_signal_initmap_(&base->sigmap);
    event_changelist_init_(&base->changelist);

    base->evbase = NULL;

    if (cfg) {
        //初始化base的dispatch 时间间隔 -1 影响epoll  select poll 阻塞时间参数 memcpy(
&base->max_dispatch_time, &cfg->max_dispatch_interval, sizeof(struct timeval)); base->limit_callbacks_after_prio = cfg->limit_callbacks_after_prio; } else { base->max_dispatch_time.tv_sec = -1; base->limit_callbacks_after_prio = 1; } if (cfg && cfg->max_dispatch_callbacks >= 0) { base->max_dispatch_callbacks = cfg->max_dispatch_callbacks; } else { base->max_dispatch_callbacks = INT_MAX; } if (base->max_dispatch_callbacks == INT_MAX && base->max_dispatch_time.tv_sec == -1) base->limit_callbacks_after_prio = INT_MAX;    // 选用事件模型  select  poll devpoll 或者epoll
   // eventops 定义选取合适模型
for (i = 0; eventops[i] && !base->evbase; i++) { if (cfg != NULL) { /* determine if this backend should be avoided */ if (event_config_is_avoided_method(cfg, eventops[i]->name)) continue; if ((eventops[i]->features & cfg->require_features) != cfg->require_features) continue; } /* also obey the environment variables */ if (should_check_environment && event_is_method_disabled(eventops[i]->name)) continue;         //指向某个模型 如epoll base->evsel = eventops[i];         //evbase 指向初始化完成的实例 base->evbase = base->evsel->init(base); } if (base->evbase == NULL) { event_warnx("%s: no event mechanism available", __func__); base->evsel = NULL; event_base_free(base); return NULL; } if (evutil_getenv_("EVENT_SHOW_METHOD")) event_msgx("libevent using: %s", base->evsel->name); /* allocate a single active event queue */ if (event_base_priority_init(base, 1) < 0) { event_base_free(base); return NULL; } /* prepare for threading */   //有关多线程的base 初始化 return (base); }

大致就时base_event 的初始化, 选取一个io复用模型, Linux下优先选择epoll。

事件生成event_new:

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;
    if (arg == &event_self_cbarg_ptr_)
        arg = ev;

    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|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;
    } 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;
        }
    }
    //初始化ev中的小根堆索引为 -1 
    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;
}

 

Libevent 事件生成

标签:elf   als   参数   eve   head   vma   should   variables   hint   

原文地址:http://www.cnblogs.com/MaAce/p/7810161.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!