1. 程式人生 > >libevent原始碼分析(1)--2.1.8--標誌資訊

libevent原始碼分析(1)--2.1.8--標誌資訊

一、事件型別  event-internal.h

/**
 * @name event flags
 *
 * Flags to pass to event_new(), event_assign(), event_pending(), and
 * anything else with an argument of the form "short events"
 */
/**@{*/
/** Indicates that a timeout has occurred.  It's not necessary to pass
 * this flag to event_for new()/event_assign() to get a timeout. */
// 定時事件
#define EV_TIMEOUT    0x01
/** Wait for a socket or FD to become readable */
// 讀事件
#define EV_READ        0x02
/** Wait for a socket or FD to become writeable */
// 寫事件
#define EV_WRITE    0x04
/** Wait for a POSIX signal to be raised*/
// 訊號
#define EV_SIGNAL    0x08
/**
 * Persistent event: won't get removed automatically when activated.
 *
 * When a persistent event with a timeout becomes activated, its timeout
 * is reset to 0.
 */
// 永久事件,啟用執行後會重新加到佇列中等待下一次啟用,否則啟用執行後會自動移除
#define EV_PERSIST    0x10
/** Select edge-triggered behavior, if supported by the backend. */
// 邊沿觸發,一般需要後臺方法支援
#define EV_ET        0x20
/**
 * If this option is provided, then event_del() will not block in one thread
 * while waiting for the event callback to complete in another thread.
 *
 * To use this option safely, you may need to use event_finalize() or
 * event_free_finalize() in order to safely tear down an event in a
 * multithreaded application.  See those functions for more information.
 *
 * THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES
 * BECOMES STABLE.
 **/
// 終止事件,如果設定這個選項,則event_del不會阻塞,需要使用event_finalize或者
// event_free_finalize以保證多執行緒安全
#define EV_FINALIZE     0x40
/**
 * Detects connection close events.  You can use this to detect when a
 * connection has been closed, without having to read all the pending data
 * from a connection.
 *
 * Not all backends support EV_CLOSED.  To detect or require it, use the
 * feature flag EV_FEATURE_EARLY_CLOSE.
 **/
// 檢查事件連線是否關閉;可以使用這個選項來檢測連結是否關閉,而不需要讀取此連結所有未決資料;
#define EV_CLOSED    0x80


二、事件狀態標誌     event_struct.h中

// 事件在time min_heap堆中
#define EVLIST_TIMEOUT        0x01
// 事件在已註冊事件連結串列中
#define EVLIST_INSERTED        0x02
// 目前未使用
#define EVLIST_SIGNAL        0x04
// 事件在啟用連結串列中
#define EVLIST_ACTIVE        0x08
// 內部使用標記
#define EVLIST_INTERNAL        0x10
// 事件在下一次啟用連結串列中
#define EVLIST_ACTIVE_LATER 0x20
// 事件已經終止
#define EVLIST_FINALIZING   0x40
// 事件初始化完成,但是哪兒都不在
#define EVLIST_INIT        0x80
// 包含所有事件狀態,用於判斷合法性的
#define EVLIST_ALL          0xff


三、後臺方法 event.c

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


四、後臺方法特徵列表 event.h

/**
   A flag used to describe which features an event_base (must) provide.
   Because of OS limitations, not every Libevent backend supports every
   possible feature.  You can use this type with
   event_config_require_features() to tell Libevent to only proceed if your
   event_base implements a given feature, and you can receive this type from
   event_base_get_features() to see which features are available.
*/
// 用來描述event_base必須提供的特徵值,其實是後臺方法提供的;
// 因為OS的限制,不是所有event_base後臺方法都支援每個可能的特徵;
// 必須使用event_config_require_features()進行配置,同時必須使用
// event_base_get_features()檢視是否支援配置的特徵。
enum event_method_feature {
    /** Require an event method that allows edge-triggered events with EV_ET. */
     // 邊沿觸發,高效但是容易丟訊息,注意與水平觸發區分
    EV_FEATURE_ET = 0x01,
    /** Require an event method where having one event triggered among
     * many is [approximately] an O(1) operation. This excludes (for
     * example) select and poll, which are approximately O(N) for N
     * equal to the total number of possible events. */
     // 要求具有很多事件的後臺方法可以以近似O(1)處理事件;select和poll
     // 無法提供這種特徵,它們只能提供近似O(N)的操作
    EV_FEATURE_O1 = 0x02,
    /** Require an event method that allows file descriptors as well as
     * sockets. */
     // 後臺方法可以處理包括sockets在內的各種檔案描述符
    EV_FEATURE_FDS = 0x04,
    /** Require an event method that allows you to use EV_CLOSED to detect
     * connection close without the necessity of reading all the pending data.
     *
     * Methods that do support EV_CLOSED may not be able to provide support on
     * all kernel versions.
     **/
     // 要求後臺方法可以使用EV_CLOSED檢測連結關閉,而不需要讀完所有未決資料才能判斷
     // 支援EV_CLOSED的後臺方法不是所有OS核心都支援的
    EV_FEATURE_EARLY_CLOSE = 0x08
};


五、event_base或者libevent工作模式 event.h

/**
   A flag passed to event_config_set_flag().
    These flags change the behavior of an allocated event_base.
    @see event_config_set_flag(), event_base_new_with_config(),
       event_method_feature
 */
// 可以使用event_config_set_flag設定以下配置。
// 這個配置可以改變event_base的行為
enum event_base_config_flag {
    /** Do not allocate a lock for the event base, even if we have
        locking set up.
        Setting this option will make it unsafe and nonfunctional to call
        functions on the base concurrently from multiple threads.
    */
     // 非阻塞模式,多執行緒不安全
    EVENT_BASE_FLAG_NOLOCK = 0x01,
    /** Do not check the EVENT_* environment variables when configuring
        an event_base  */
     // 這種模式下不再檢查EVENT_*環境變數
    EVENT_BASE_FLAG_IGNORE_ENV = 0x02,
    /** Windows only: enable the IOCP dispatcher at startup
        If this flag is set then bufferevent_socket_new() and
        evconn_listener_new() will use IOCP-backed implementations
        instead of the usual select-based one on Windows.
     */
     // 只應用於windows環境
    EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,
    /** Instead of checking the current time every time the event loop is
        ready to run timeout callbacks, check after each timeout callback.
     */
     // 每次event_loop準備執行timeout回撥時,不再檢查當前的時間,而是
     // 在每次timeout回撥之後檢查
    EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08,

    /** If we are using the epoll backend, this flag says that it is
        safe to use Libevent's internal change-list code to batch up
        adds and deletes in order to try to do as few syscalls as
        possible.  Setting this flag can make your code run faster, but
        it may trigger a Linux bug: it is not safe to use this flag
        if you have any fds cloned by dup() or its variants.  Doing so
        will produce strange and hard-to-diagnose bugs.
        This flag can also be activated by setting the
        EVENT_EPOLL_USE_CHANGELIST environment variable.
        This flag has no effect if you wind up using a backend other than
        epoll.
     */
     // 如果後臺方法是epoll,則此模式是指可以安全的使用libevent內部changelist
     // 進行批量增刪而儘可能減少系統呼叫。這種模式可以讓程式碼效能更高,
     // 但是可能會引起Linux bug:如果有任何由dup()或者他的變數克隆的fds,
     // 則是不安全的。這樣做會引起奇怪並且難以檢查的bugs。此模式可以通過
     // EVENT_EPOLL_USE_CHANGELIST環境變數啟用。
     // 此模式只有在使用epoll時可用
    EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10,

    /** Ordinarily, Libevent implements its time and timeout code using
        the fastest monotonic timer that we have.  If this flag is set,
        however, we use less efficient more precise timer, assuming one is
        present.
     */
     // 通常情況下,libevent使用最快的monotonic計時器實現自己的計時和超時控制;
     // 此模式下,會使用效能較低但是準確性更高的計時器。
    EVENT_BASE_FLAG_PRECISE_TIMER = 0x20
};


六、事件關閉時的回撥函式模式型別 

/** @name Event closure codes
    Possible values for evcb_closure in struct event_callback
    @{
 */
/** A regular event. Uses the evcb_callback callback */
// 常規事件,使用evcb_callback回撥
#define EV_CLOSURE_EVENT 0
/** A signal event. Uses the evcb_callback callback */
// 訊號事件;使用evcb_callback回撥
#define EV_CLOSURE_EVENT_SIGNAL 1
/** A persistent non-signal event. Uses the evcb_callback callback */
// 永久性非訊號事件;使用evcb_callback回撥
#define EV_CLOSURE_EVENT_PERSIST 2
/** A simple callback. Uses the evcb_selfcb callback. */
// 簡單回撥,使用evcb_selfcb回撥
#define EV_CLOSURE_CB_SELF 3
/** A finalizing callback. Uses the evcb_cbfinalize callback. */
// 結束的回撥,使用evcb_cbfinalize回撥
#define EV_CLOSURE_CB_FINALIZE 4
/** A finalizing event. Uses the evcb_evfinalize callback. */
// 結束事件回撥,使用evcb_evfinalize回撥
#define EV_CLOSURE_EVENT_FINALIZE 5
/** A finalizing event that should get freed after. Uses the evcb_evfinalize
 * callback. */
// 結束事件之後應該釋放,使用evcb_evfinalize回撥
#define EV_CLOSURE_EVENT_FINALIZE_FREE 6
/** @} */


相關推薦

libevent原始碼分析62.1.8建立和釋放libevent控制代碼event_base的相關函式

一、event_base_new 建立預設的event_base ** * Create and return a new event_base to use with the rest of Libevent. * * @return a new event_ba

libevent原始碼分析

libevent-1.4/sample/signal-test.c event_add(&signal_int, NULL); 將 struct event signal_int新增到struct event_base* base,即註冊號監聽事件以及回

libevent原始碼分析

libevent-1.4/sample/singnal-test.c 接下來看看 event_base_dispatch(base); 這個函式是整個Reactor的核心,是一個loop. 函式定義: int event_base_dispatch(struct

Libevent原始碼分析--- libevent事件機制

之前幾個章節都是分析libevent的輔助功能,這一節將要詳細分析libevent處理事件的流程和機制,在分析之前先看一下libevent的使用方法,本文也將以libevent的使用方式入手來分析libevent的工作機制。 void cb_func(ev

libevent原始碼分析

還是上次那個訊號函式的例子, sample/signal-test.c——註冊訊號以及回撥事件。 /* Initalize one event */ event_set(&signal_int, SIGINT, EV_SIGNAL|EV_PERSIST,

Libevent原始碼分析--- IOCP

event_base中有一個iocp變數,event_base的初始化函式中會呼叫event_base_start_iocp開啟iocp功能,event_base_start_iocp又會呼叫event_iocp_port_launch來初始化IOCP:

libevent原始碼分析

libevet——Reactor初始化,先來看看event_base_new的定義,先關注主線程式碼,後續研究細節: struct event_base *event_base_new(void) { int i; struct event_base *ba

Libevent原始碼分析--- bufferevent

上一節說過,libevent提供六種bufferevent型別,後面會詳細分析其中的兩個:bufferevent_sock和bufferevent_async.下面是bufferevent的詳細定義: struct bufferevent { /*

Libevent原始碼分析--- evbuffer的基本操作

之前幾節分析了libevent底層的結構和執行機制,接下來的幾節將會分析Bufferevents,Bufferevents在event的基礎上加入了資料快取邏輯,使得事件和資料結合在一起。libevent的bufferevent有六種型別,分別是:buffere

libevent原始碼分析82.1.8事件申請與釋放

一、event_new 主要用來建立事件結構體,根據監聽事件型別,檔案描述符,以及回撥函式,回撥函式引數等建立,可以看成是事件的初始化過程,主要是設定事件的初始狀態,此時事件結構體剛剛創建出來還沒有新增到event_base的啟用或者等待列表中,是孤立存在的,需要呼叫eve

libevent原始碼分析12.1.8標誌資訊

一、事件型別  event-internal.h /** * @name event flags * * Flags to pass to event_new(), event_assign(), event_pending(), and * anything e

libevent原始碼分析22.1.8結構體 struct event和struct event_callback

一、event_callback結構體 struct event_callback { //下一個回撥事件 TAILQ_ENTRY(event_callback) evcb_active_next; //回撥事件的狀態標識,具體為:

libevent原始碼分析1

有過看nginx原始碼的基礎,現在來看libevent原始碼,感覺要輕鬆多了。。 第一篇文章,主要是還是介紹一些幾個重要的資料結構吧。。。。 首先是event結構:struct event { TAILQ_ENTRY (event) ev_next; //用於構成eve

libevent原始碼分析細節版1

從sample/hello-world.c來剖析libevent原始碼 我準備從libevent原始碼中最簡單的sample開始剖析原始碼。目前思路是dfs的方法,即碰到一個不夠底層的封裝,就去深究它,直到徹底搞懂它,然後返回繼續。 先上hello-worl

Spring原始碼分析IoC容器的實現1

    Ioc(Inversion of Control)——“控制反轉”,不是什麼技術,而是一種設計思想。在Java開發中,Ioc意味著將你設計好的物件交給容器控制,而不是傳統的在你的物件內部直接控制。理解好Ioc的關鍵是要明確“誰控制誰,控制什麼,為何是反轉(有

Android7.1 [Camera] Camera Hal 原始碼分析

原始碼平臺:rk3399   命令列ls看下原始碼的結構 hardware/rockchip/camera/CameraHal: lib目錄 原始碼的檔案看起來有點多,我們看看Android.mk檔案, 這些檔案最終編譯成camera.rk30bo

Spring原始碼分析IoC容器的依賴注入1

    依賴注入的過程是使用者第一次向IoC容器索要Bean時才觸發的,當然也有例外,可以在BeanDefinition資訊中通過控制lazy-init屬性來讓容器完成對Bean的預例項化。這個預例項化實際上也是一個完成依賴注入的過程,但它是在初始化的過程中完成的。

1.1spring啟動原始碼分析ClassPathXmlApplicationContext

spring啟動原始碼分析(ClassPathXmlApplicationContext) Applicantioncontext uml圖 ClassPathXmlApplicationContext xml 配置檔案專案中的路徑 FileSystemXml

spring4.2.9 java專案環境下ioc原始碼分析——refresh之obtainFreshBeanFactory方法@1準備工作與載入Resource

obtainFreshBeanFactory方法從字面的意思看獲取新的Bean工廠,實際上這是一個過程,一個載入Xml資源並解析,根據解析結果組裝BeanDefinitions,然後初始化BeanFactory的過程。在載入Xml檔案之前,spring還做了一些其他的工作,比

AFNetworking3.1.0原始碼分析詳解AFHTTPRequestSerializer 之初始化方法

1:類圖介紹 在AFHTTPSessionManager 初始化方法中可以看到 AFNetworking 預設使用的網路請求序列化類是AFHTTPRequestSerializer,一下是關於它的類圖: 2:類功能分析:  一:初始化函式: - (instancetyp