zoukankan      html  css  js  c++  java
  • Libevent源码分析—event_init()

    下面开始看初始化event_base结构的相关函数。相关源码位于event.c

    event_init()

    首先调用event_init()初始化event_base结构体
    struct event_base *
    event_init(void)
    {
        struct event_base *base = event_base_new();    //event_init()调用event_base_new()
        if (base != NULL)
            current_base = base;
        return (base);
    }

    我们发现event_init()工作量很少,只是调用event_base_new()函数,所以真正初始化event_base的工作是在event_base_new()函数内完成。

    event_base_new()

    struct event_base *
    event_base_new(void)    //初始化libevent的event_base
    {
        int i;
        struct event_base *base;
        if ((base = calloc(1, sizeof(struct event_base))) == NULL)    //在堆上分配内存存储event_base,所有字段初始化为0
            event_err(1, "%s: calloc", __func__);
        event_sigcb = NULL;
        event_gotsig = 0;
        detect_monotonic();    //设置use_monotonic变量
        gettime(base, &base->event_tv);    //base->tv_cache.tv_sec非0,则赋给base->event_tv
        
        min_heap_ctor(&base->timeheap);    //初始化定时事件的小根堆base->timeheap    min_heap.h
        TAILQ_INIT(&base->eventqueue);    //初始化注册事件链表base->eventqueue    sys/queue.h
        base->sig.ev_signal_pair[0] = -1;    //初始化信号base->sig
        base->sig.ev_signal_pair[1] = -1;
        
        base->evbase = NULL;    //初始化I/O多路复用 base->evbase
        //遍历全局数组eventops[],初始化libevent的I/O多路复用机制
        for (i = 0; eventops[i] && !base->evbase; i++) {    //以NULL标志数组结尾,只选取一个I/O多路复用机制
            base->evsel = eventops[i];    //初始化base->evsel
            base->evbase = base->evsel->init(base);    //初始化base->evbase
        }
        if (base->evbase == NULL)    //没有I/O多路复用
            event_errx(1, "%s: no event mechanism available", __func__);
        if (evutil_getenv("EVENT_SHOW_METHOD")) //调用getenv()获取环境变量EVENT_SHOW_METHOD    evutil.c
            event_msgx("libevent using: %s
    ",
                   base->evsel->name);
        /* allocate a single active event queue */
        //event_base_new()内调用event_base_priority_init()
        event_base_priority_init(base, 1);    //设置优先级base->nactivequeues;分配数组base->activequeues。数组大小和优先级相同
        return (base);
    }

    其中由3点需要注意:

    1.该函数调用calloc()在堆上分配内存来存储event_base;

    2.使用全局数组eventops[]存储系统支持的I/O多路复用机制,然后遍历该数组,选取第1个I/O多路复用机制。

    3.libevent支持event有优先级,所以又调用了event_base_priority_init()来完成优先级相关的设置。

    event_base_priority_init()

    //设置不同event的优先级,值越小,优先级越高
    //返回值:0,成功;-1,出错
    int
    event_base_priority_init(struct event_base *base, int npriorities)
    {
        int i;
        if (base->event_count_active)    //当前base上有活跃的events则不能设置优先级,返回。
            return (-1);
        if (npriorities == base->nactivequeues)    //设置的优先级和当前优先级相同,则直接返回
            return (0);
        if (base->nactivequeues) {    //不同,则先释放原先的activequeues数组
            for (i = 0; i < base->nactivequeues; ++i) {
                free(base->activequeues[i]);
            }
            free(base->activequeues);
        }
        /* Allocate our priority queues */
        base->nactivequeues = npriorities;    //设置新的优先级
        base->activequeues = (struct event_list **)
            calloc(base->nactivequeues, sizeof(struct event_list *));    //设置和优先级值相同大小的event_list数组
        if (base->activequeues == NULL)
            event_err(1, "%s: calloc", __func__);
        for (i = 0; i < base->nactivequeues; ++i) {
            base->activequeues[i] = malloc(sizeof(struct event_list));    //初始化activequeues数组中每个元素
            if (base->activequeues[i] == NULL)
                event_err(1, "%s: malloc", __func__);
            TAILQ_INIT(base->activequeues[i]);
        }
        return (0);
    }

    该函数设置优先级,初始化了event_base的nactivequeues成员和activequeues成员。优先级值越小,优先级越高。在活跃事件链表中,优先级高的event先被处理。

  • 相关阅读:
    2020.10.23 19级training 补题报告
    2020.10.17 天梯赛练习 补题报告
    2020.10.16 19级training 补题报告
    2020.10.9 19级training 补题报告
    2020.10.10 天梯赛练习 补题报告
    2020.10.3 天梯赛练习 补题报告
    2020.10.2 19级training 补题报告
    第十届山东省ACM省赛复现补题报告
    VVDI Key Tool Plus Adds VW Passat 2015 Key via OBD
    Xhorse VVDI Prog Software V5.0.3 Adds Many MCUs
  • 原文地址:https://www.cnblogs.com/zxiner/p/6920061.html
Copyright © 2011-2022 走看看