• libevent(三)event_base


    libevent能够处理三种事件: I/O、定时器、信号。

    event_base

        统一管理所有事件。

    struct event_base {
        const struct eventop *evsel;    // backend
        void *evbase;                   /** Pointer to backend-specific data. */
    
        const struct eventop *evsigsel; // signal backend
        struct evsig_info sig;          /** Data to implement the common signal handelr code. */
        
        int event_count;                // 事件总数
        int event_count_active;         // 激活事件总数
        
        struct event_list eventqueue;   // 存储所有事件,但不包括定时器事件
        struct event_io_map io;         // 存储I/O事件
        struct event_signal_map sigmap; // 存储信号事件
        struct min_heap timeheap;       // 存储定时器事件
        
        /* Active event management. */
        /** An array of nactivequeues queues for active events (ones that
         * have triggered, and whose callbacks need to be called).  Low
         * priority numbers are more important, and stall higher ones.
         */
        struct event_list *activequeues;
        /** The length of the activequeues array */
        int nactivequeues;
        
        ...
    };

    eventop

        用于描述event_base的底层实现机制

    /** Structure to define the backend of a given event_base. */
    struct eventop {
        const char *name;
        void *(*init)(struct event_base *);
        int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
        int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
        int (*dispatch)(struct event_base *, struct timeval *);
        void (*dealloc)(struct event_base *);
        int need_reinit;
        enum event_method_feature features;
        size_t fdinfo_len;
    };

    libevent支持多种平台,因此定义了一个全局数组来存放多个eventop。

    /* Array of backends in order of preference. */
    static const struct eventop *eventops[] = {
    #ifdef _EVENT_HAVE_EVENT_PORTS
        &evportops,
    #endif
    #ifdef _EVENT_HAVE_WORKING_KQUEUE
        &kqops,
    #endif
    #ifdef _EVENT_HAVE_EPOLL
        &epollops,
    #endif
    #ifdef _EVENT_HAVE_DEVPOLL
        &devpollops,
    #endif
    #ifdef _EVENT_HAVE_POLL
        &pollops,
    #endif
    #ifdef _EVENT_HAVE_SELECT
        &selectops,
    #endif
    #ifdef WIN32
        &win32ops,
    #endif
        NULL
    };

    Linux平台的I/O多路复用机制是epoll,对应epollops。

    const struct eventop epollops = {
        "epoll",
        epoll_init,
        epoll_nochangelist_add,
        epoll_nochangelist_del,
        epoll_dispatch,
        epoll_dealloc,
        1, /* need reinit */
        EV_FEATURE_ET|EV_FEATURE_O1,
        0
    };

    在event_base中,evsigsel也对应一个后端,这个后端用于信号处理。

    值得注意的是这个成员的初始化时间:

    int
    evsig_init(struct event_base *base)
    {
        /*
         * Our signal handler is going to write to one end of the socket
         * pair to wake up our event loop.  The event loop then scans for
         * signals that got delivered.
         */
        if (evutil_socketpair(
                AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1) {
    #ifdef WIN32
            /* Make this nonfatal on win32, where sometimes people
               have localhost firewalled. */
            event_sock_warn(-1, "%s: socketpair", __func__);
    #else
            event_sock_err(1, -1, "%s: socketpair", __func__);
    #endif
            return -1;
        }
    
        evutil_make_socket_closeonexec(base->sig.ev_signal_pair[0]);
        evutil_make_socket_closeonexec(base->sig.ev_signal_pair[1]);
        base->sig.sh_old = NULL;
        base->sig.sh_old_max = 0;
    
        evutil_make_socket_nonblocking(base->sig.ev_signal_pair[0]);
        evutil_make_socket_nonblocking(base->sig.ev_signal_pair[1]);
    
        event_assign(&base->sig.ev_signal, base, base->sig.ev_signal_pair[1],
            EV_READ | EV_PERSIST, evsig_cb, base);
    
        base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;
        event_priority_set(&base->sig.ev_signal, 0);
    
        base->evsigsel = &evsigops;
    
        return 0;
    }

     evsigops结构如下:

    static const struct eventop evsigops = {
        "signal",
        NULL,
        evsig_add,
        evsig_del,
        NULL,
        NULL,
        0, 0, 0
    };
  • 相关阅读:
    C++/C编程指南之基本语句
    利用Lucene.net对附件做搜索
    验证码的破解思路!
    javascript中replace的正则表达式语法
    让数据库访问组件支持Using
    C#读写文件总结
    net use命令详细解释
    利用SQL语句清理日志
    彻底修改Google Chrome浏览器的安装目录
    oracle sqlplus 常用命令大全
  • 原文地址:https://www.cnblogs.com/gattaca/p/7680389.html
Copyright © 2020-2023  润新知