1. 程式人生 > >glusterfs 4.0.1 event模塊 分析筆記1

glusterfs 4.0.1 event模塊 分析筆記1

eight define register span data 線程id 為我 style rec

1. 前言

在C語言i中,存儲變量的結構體加上一組函數指針,大概就可以算是一個對象模型了;如果將一組函數指針捆綁為結構體,

後期根據配置或者環境需要綁定到不同實現模塊中的一組函數,可以認為是C語言面對對象的設計實現了。

2. 概述

事件模型,定義在"libgusterfs/src/"下幾個文件中:

event.h    // 事件模型的接口定義:各個結構體的定義
event.c    // 實現了最基本的模型的管理相關的函數
eventpool.c // pool模式 具體的實現
eventepoll.c // epool模式,具體的實現

我們首先看看如何定義事件管理模型:

struct event_pool {
	struct event_ops *ops;          // 一組函數指針,

	int fd;                         // 文件操作符
	int breaker[2];

	int count;
	struct event_slot_poll  *reg;                          // poll 模式使用的,定義於eventpool.c
	struct event_slot_epoll *ereg[EVENT_EPOLL_TABLES];     // 定義於eventepoll.c
	int slots_used[EVENT_EPOLL_TABLES];                    // #define 
EVENT_EPOLL_TABLES 1024 int used; int changed; pthread_mutex_t mutex; pthread_cond_t cond; void *evcache; int evcache_size; /* 備註: 目前當使用Epoll模式工作時候使用下面部分代碼 */
int eventthreadcount; /* 內部執行線程個數 */ pthread_t pollers[EVENT_MAX_THREADS]; /* poller 線程ID 集合 */ int destroy; int activethreadcount; /* * 自動縮放的線程數, 這個數加到已經配置的線程數上. 這僅僅適用於server端, 因為我們將試圖將線程數匹配 * bricks的數目. 對客戶或者 GlusterD來說, * 這個變量一直為0。 * * 下一步: 也會考慮為客戶端縮放線程數。 */ int auto_thread_count; };

這個結構體包括了poll和epoll兩種工作模式的不同實現。

接著定義了一組函數指針:

struct event_ops 
{ struct event_pool * (*new) (int count, int eventthreadcount); int (*event_register) (struct event_pool *event_pool, int fd, event_handler_t handler, void *data, int poll_in, int poll_out); int (*event_select_on) (struct event_pool *event_pool, int fd, int idx, int poll_in, int poll_out); int (*event_unregister) (struct event_pool *event_pool, int fd, int idx); int (*event_unregister_close) (struct event_pool *event_pool, int fd, int idx); int (*event_dispatch) (struct event_pool *event_pool); int (*event_reconfigure_threads) (struct event_pool *event_pool, int newcount); int (*event_pool_destroy) (struct event_pool *event_pool); int (*event_handled) (struct event_pool *event_pool, int fd, int idx, int gen); };

這組函數指針在具體實現中將綁定具體的實現,綁定的過程定義於event_pool_new (int count, int eventthreadcount):

struct event_pool * event_pool_new (int count, int eventthreadcount)
{
        struct event_pool *event_pool = NULL;     // 返回值
	extern struct event_ops event_ops_poll;   // 引用外部結構體,見  eventpool.c  最後面部分

#ifdef HAVE_SYS_EPOLL_H                           // 如果支持epoll
	extern struct event_ops event_ops_epoll;  // 引用外部結構體,見 eventepool.c 最後面部分
        event_pool = event_ops_epoll.new (count, eventthreadcount);    // 執行pool模塊的生成函數
        if (event_pool)    
       {
                event_pool->ops = &event_ops_epoll;                    // 綁定該模塊的操作函數
        } 
    else         
       {
                gf_msg ("event", GF_LOG_WARNING, 0, LG_MSG_FALLBACK_TO_POLL, "falling back to poll based event handling");
        }
#endif

        if (!event_pool)        
       {
                event_pool = event_ops_poll.new (count, eventthreadcount);     // 執行epool模塊的生成函數

                if (event_pool)
                        event_pool->ops = &event_ops_poll;                     // 綁定該模塊的操作函數
        }

        return event_pool;
}

而整個event.c中定義的各個函數,僅僅是調用綁定pool或者epoll實現的各個函數。舉例如下:

int event_select_on (struct event_pool *event_pool, int fd, int idx_hint, int poll_in, int poll_out)
{
       int ret = event_pool->ops->event_select_on (event_pool, fd, idx_hint, poll_in, poll_out);
    return ret; }

3. epoll 模型的實現

我們首先看看典型的epoll模型如何實現:epoll模型和使用詳解(精髓)epoll - I/O event notification facility

未完待續

glusterfs 4.0.1 event模塊 分析筆記1