libevent代码阅读(1)

一些概念:

1、libevent是一个高性能的io框架,基于Reactor模式

2、event_base即Reactor实例

3、event是事件处理器(注意event不是事件,而是事件处理器)

4、libevent实现了select、poll、epoll、iocp等io复用机制,在编译的时候会自动选择一个最高效io复用机制

5、本次的代码阅读基于libevent2.0


event_base结构

// 一个event_base就是一个Reactor实例
struct event_base {
	/** Function pointers and other data to describe this event_base's
	 * backend. */
	// 初始化Reactor的时候选择一种后端io复用机制,并记录到如下字段中
	const struct eventop *evsel;

	/** Pointer to backend-specific data. */
	// 指向io复用机制真正存储的数据,它通过evsel的init函数莱初始化
	void *evbase;

	/** List of changes to tell backend about at next dispatch.  Only used
	 * by the O(1) backends. */
	/*
	 * 事件变化队列,其用途是:如果一个文件描述符上注册的事件被多次修改
	 * 则可以使用缓冲区来避免重复的系统调用(如epoll_ctl)。它仅能用于时间复杂度为0(1)的io复用技术
	 */
	struct event_changelist changelist;

	/** Function pointers used to describe the backend that this event_base
	 * uses for signals */
	// 指向信号后端处理机制,目前仅仅定义了一种处理方法
	const struct eventop *evsigsel;

	/** Data to implement the common signal handelr code. */
	// 信号事件处理器使用的数据结构,其中封装了一个由socketpair创建的管道
	// 它用于信号处理函数和事件多路分发器之间的通信
	struct evsig_info sig;

	/** Number of virtual events */
	// 虚拟事件的数量
	int virtual_event_count;

	/** Number of total events added to this event_base */
	// 所有事件的数量
	int event_count;

	/** Number of total events active in this event_base */
	// 激活事件的数量
	int event_count_active;

	/** Set if we should terminate the loop once we're done processing
	 * events. */
	// 是否执行完活动事件队列上的剩余的任务之后就退出事件循环
	int event_gotterm;

	/** Set if we should terminate the loop immediately */
	// 是否立即退出事件循环
	int event_break;

	/** Set if we should start a new instance of the loop immediately. */
	// 是否启动一个新的事件循环
	int event_continue;

	/** The currently running priority of events */
	// 目前正在处理的活动事件队列的优先级
	int event_running_priority;

	/** Set if we're running the event_base_loop function, to prevent
	 * reentrant invocation. */
	// 事件循环是否已经启动
	int running_loop;

	/* 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;

	/* common timeout logic */

	/** An array of common_timeout_list* for all of the common timeout
	 * values we know. */
	// 下面三个成员用于管理通用定时器队列
	struct common_timeout_list **common_timeout_queues;

	/** The number of entries used in common_timeout_queues */
	int n_common_timeouts;

	/** The total size of common_timeout_queues. */
	int n_common_timeouts_allocated;

	/** List of defered_cb that are active.  We run these after the active
	 * events. */
	/*
	 * 存放延迟回调函数的链表
	 * 事件循环每次成功处理完一个活动队列中的所有事件之后,就掉用一次延迟回调函数
	 */
	struct deferred_cb_queue defer_queue;

	/** Mapping from file descriptors to enabled (added) events */
	// 文件描述符和io事件处理器之间的关系
	struct event_io_map io;

	/** Mapping from signal numbers to enabled (added) events. */
	// 信号值和信号事件之间的映射关系
	struct event_signal_map sigmap;

	/** All events that have been enabled (added) in this event_base */
	// 注册事件队列,存放io事件处理器和信号事件处理器
	struct event_list eventqueue;

	/** Stored timeval; used to detect when time is running backwards. */
	struct timeval event_tv;

	/** Priority queue of events with timeouts. */
	// 时间堆
	struct min_heap timeheap;

	/** Stored timeval: used to avoid calling gettimeofday/clock_gettime
	 * too often. */
	struct timeval tv_cache;

#if defined(_EVENT_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
	/** Difference between internal time (maybe from clock_gettime) and
	 * gettimeofday. */
	struct timeval tv_clock_diff;
	/** Second in which we last updated tv_clock_diff, in monotonic time. */
	time_t last_updated_clock_diff;
#endif

	// 多线程支持
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
	/* threading support */
	/** The thread currently running the event_loop for this base */
	// 当前运行该event_base的事件循环的线程
	unsigned long th_owner_id;

	/** A lock to prevent conflicting accesses to this event_base */
	// event_base的独占锁
	void *th_base_lock;

	/** The event whose callback is executing right now */
	// 当前事件循环正在执行那个事件处理器的回调函数
	struct event *current_event;

	/** A condition that gets signalled when we're done processing an
	 * event with waiters on it. */
	// 条件变量
	void *current_event_cond;

	/** Number of threads blocking on current_event_cond. */
	// 等待current_event_cond的线程数量
	int current_event_waiters;
#endif

#ifdef WIN32
	/** IOCP support structure, if IOCP is enabled. */
	// win32下的完成端口
	struct event_iocp_port *iocp;
#endif

	/** Flags that this base was configured with */
	// 一些配置参数
	enum event_base_config_flag flags;

	/* Notify main thread to wake up break, etc. */
	/** True if the base already has a pending notify, and we don't need
	 * to add any more. */
	// 下面这组变量给工作线程唤醒主线程提供了方法(使用socketpair创建的管道)
	int is_notify_pending;

	/** A socketpair used by some th_notify functions to wake up the main
	 * thread. */
	evutil_socket_t th_notify_fd[2];
	/** An event used by some th_notify functions to wake up the main
	 * thread. */
	struct event th_notify;
	/** A function used to wake up the main thread from another thread. */
	int (*th_notify_fn)(struct event_base *base);
};


event结构

// 一个event是一个事件处理器
struct event {
    // 所有的被激活的事件处理器通过该成员串联成一个尾队列(有多个活动事件队列,按照不同的优先级来划分)
	TAILQ_ENTRY(event) ev_active_next;

    // 所有的已注册事件构成一个尾队列
	TAILQ_ENTRY(event) ev_next;

	/* for managing timeouts */
    // 用于定时事件(定时器)
    // 老版本的定时器由时间堆来管理,由min_heap_idx成员来标志
    // 新版本的通用的定时器由简单的链表(尾队列)来管理,由ev_next_with_common_timeout来标志其在队列中的位置
	union {
		TAILQ_ENTRY(event) ev_next_with_common_timeout;
		int min_heap_idx;
	} ev_timeout_pos;

    // 对于io事件,它是文件描述符
    // 对于信号事件,它是信号值
	evutil_socket_t ev_fd;

    // 指向Reactor实例
	struct event_base *ev_base;


    // _ev:
    // 或者存放相同文件描述符的io事件处理的队列,例如一个套接字可读可写、出错等等
    // 或者存放相同信号值的信号事件处理器的队列(即信号事件处理器的队列)
	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 */
            //该参数要么是0,要么指向ev_ncalls
			short *ev_pncalls;
		} ev_signal;
	} _ev;

    // 事件类型
    short ev_events;

    // 记录当前激活事件的类型
	short ev_res;		/* result passed to event callback */

    // 一些事件标志 即一些EVLIST开头的宏的标志
	short ev_flags;

    // 事件处理器的优先级,值越小优先级越高
	ev_uint8_t ev_pri;	/* smaller numbers are higher priority */

    // 指定event——base执行事件处理器的回调函数时候的行为
    // 可选值位于event-internal.h中
	ev_uint8_t ev_closure;

    // 超时时间,仅仅对定时器有效
	struct timeval ev_timeout;

	/* allows us to adopt for different types of events */
    // 处理事件的回调函数,需要自己实现
    // 它的三个参数分别是:ev_fd,ev_res,ev_arg
	void (*ev_callback)(evutil_socket_t, short, void *arg);

    // 回调函数的参数
	void *ev_arg;
};


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值