1. 程式人生 > >libevent原始碼分析---回顧主要的結構體

libevent原始碼分析---回顧主要的結構體

         以前忘記說明,這裡原始碼分析使用的是libevent庫的1.4.12-stable版本,在2.0以上的版本都是4W+行,過於龐大,網路上看到關於libevent庫中幾個重要的結構體關係圖,很清楚很好,感謝原作者的細緻:

(虛線部分代表包含關係)

一、tail_queue

       關於tail_queue的解釋在上篇文章中很細緻。

二、event

//event提供了函式介面,供Reactor在事件發生時呼叫,以執行相應的事件處理,
//通常它會繫結一個有效的控制代碼(ev_fd)做為回撥函式的引數.
struct event {

	//已註冊事件佇列入口
	TAILQ_ENTRY (event) ev_next;

	//已啟用事件佇列入口
	TAILQ_ENTRY (event) ev_active_next;

	//訊號事件佇列入口 不過在以前的分析中可以看到,將來這個佇列中的內容會被新增到ev_active_next佇列中。
	TAILQ_ENTRY (event) ev_signal_next;

	//表示該event在定時器事件最小堆min_heap的索引
	unsigned int min_heap_idx;	/* for managing timeouts */

	//該事件所屬的反應堆例項
	struct event_base *ev_base;

	//對於I/O事件,是繫結的檔案描述符; 對於signal事件,是繫結的訊號.
	int ev_fd;

	//表示事件型別: I/O,定時器或者訊號
	short ev_events;

	//事件就緒執行時,將要呼叫ev_callback 的次數,通常為1
	short ev_ncalls;

	//該事件的超時時間,在定時器最小堆min_heap操作中作為節點值進行比較.
	struct timeval ev_timeout;

	//該事件的優先順序,越小越優先.
	int ev_pri;		/* smaller numbers are higher priority */

	//該事件被啟用時的回撥函式
	void (*ev_callback)(int, short, void *arg);

	//該事件的標記資訊,表示其當前的狀態,即它在哪個連結串列中
	int ev_flags;

	... //其他成員.
};

 一個事件是可以插入到多個佇列的,當它與一個反應堆例項(event_base)關聯時,這個事件被插入到反應堆例項下的已註冊事件佇列 event_base -> eventqueue ,當它處於就緒狀態時,會被插入到反應堆例項下的已啟用事件佇列 event_base -> activequeues[id], id = event -> ev_pri .同時,如果此事件是訊號事件,那麼它會被插入到反應堆結構體下的訊號事件結構體下的訊號佇列 event_base -> evsignal_info -> evsigevents[id], id = event -> ev_fd .

需要指出的,每個事件都保持了一個成員 struct event_base *ev_base; ,它表示該事件屬於哪個反應堆例項.

還有一個成員需要注意, short ev_events; ,它表明此事件的事件型別,libevent正是基於此實現對I/O,訊號,定時 3種事件的封裝的.

一般使用情況下,不申請struct event_base.因為在庫中有一個全域性的event_base,所有的事件都可以新增到這個全域性event_base中!!!

三、min_heap

typedef struct min_heap
{
    struct event** p; //p指向一個動態分配的陣列,陣列元素是event指標.
    unsigned n, a; // n表示目前儲存了多少元素,a表示p指向的記憶體能夠儲存event指標的個數.
} min_heap_t;

這個結構體的作用這裡就不再累述

四、evsignal_info

       這個結構體是用來管理訊號事件的

struct evsignal_info {

	//是否有訊號發生的標記
	volatile sig_atomic_t evsignal_caught;

	//evsigevents[signo]表示註冊到訊號 signo 的事件連結串列
	struct event_list evsigevents[NSIG];

	//具體記錄每個訊號觸發的次數,evsigcaught[signo]是記錄訊號signo被觸發的次數
	sig_atomic_t evsigcaught[NSIG];

	... //其他成員
};

其中, struct event_list evsigevents[NSIG]; 成員是一個數組,它的元素 evsigevents[id] 表示註冊到訊號id的事件連結串列.

還有其他幾個更加重要的結構體

event_base