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; // 可以需要监控的SOCKET个数
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个表格,每个表格里有1024个槽位,每个槽位是一个SOCKET
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

在event-epoll.c 中定义了epoll实现的接口函数,

struct event_ops event_ops_epoll =
{
.new = event_pool_new_epoll, // 新建立一个event-pool,创建epoll句柄
.event_register = event_register_epoll, // 将一个新的socket添加到epoll的监控中,
.event_select_on = event_select_on_epoll, //
.event_unregister = event_unregister_epoll, // 取消监控
.event_unregister_close = event_unregister_close_epoll, // 取消监控并关闭socket
.event_dispatch = event_dispatch_epoll, // 建立pollercount个线程,event_dispatch_epoll_worker 线程函数用来处理消息,
// 并在event_dispatch_epoll_handler 中调用注册的函数
.event_reconfigure_threads = event_reconfigure_threads_epoll,
.event_pool_destroy = event_pool_destroy_epoll, // 销毁池
.event_handled = event_handled_epoll,
};

glusterfs 4.0.1 event模块 分析笔记1的更多相关文章

  1. glusterfs 4.0.1 api 分析笔记1

    一般来说,我们写个客户端程序大概的样子是这样的: /* glfs_example.c */ // gcc -o glfs_example glfs_example.c -L /usr/lib64/ - ...

  2. glusterfs 4.0.1 rpc 分析笔记1

    Jimmy的文档:Glusterfs的rpc模块分析 第一节.rpc服务器端实现原理及代码分析 第二节.rpc客户端实现原理及代码分析 第三节.rpc通信过程分析 经过阅读源码对比之前提及的文档,我个 ...

  3. nginx源码分析——event模块

    源码:nginx 1.12.0   一.简介      nginx是一款非常受欢迎的软件,具备高性能.模块化可定制的良好特性.之前写了一篇nginx的http模块分析的文章,主要对http处理模块进行 ...

  4. 一个普通的 Zepto 源码分析(三) - event 模块

    一个普通的 Zepto 源码分析(三) - event 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块, ...

  5. jQuery源码分析--Event模块(1)

    jQuery的Event模块提供了强大的功能:事件代理,自定义事件,自定义数据等.今天记录一下它实现的原理. 我们都知道,在js的原生事件中,有事件对象和回调函数这两样东西.但是事件对象是只读的,所以 ...

  6. Backbone源码解析(一):Event模块

    Backbone是一个当下比较流行的MVC框架.它主要分为以下几个模块: Events, View, Model, Collection, History, Router等几大模块.它强制依赖unde ...

  7. nginx事件模块分析(一)

    nginx ngx_events_module模块分析 ngx_events_module模块是核心模块之一,它是其它所有事件模块的代理模块.nginx在启动时只与events模块打交道,而由even ...

  8. [自娱自乐] 3、超声波测距模块DIY笔记(三)

    前言 上一节我们已经研究了超声波接收模块并自己设计了一个超声波接收模块,在此基础上又尝试用单片机加反相器构成生成40KHz的超声波发射电路,可是发现采用这种设计的发射电路存在严重的发射功率太低问题,对 ...

  9. 读Zepto源码之Event模块

    Event 模块是 Zepto 必备的模块之一,由于对 Event Api 不太熟,Event 对象也比较复杂,所以乍一看 Event 模块的源码,有点懵,细看下去,其实也不太复杂. 读Zepto源码 ...

随机推荐

  1. django处理cookie的机制

    title: django处理cookie的机制 tags: djaogo, cookie, session grammar_cjkRuby: true --- cookie的意义 在多数日常使用的网 ...

  2. 关于kali linux 2.0的vmware tools的安装问题

    在安装好kali linux 2.0 后,首先要做的就是添加源并更新系统,否则会出现软件定位问题. 在kali 2.0中,vmware tools已经不能使用了,官方放了一个工具下载安装就好. 添加源 ...

  3. redis入门(03)redis的配置

    一.配置文件 Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf.你可以通过 CONFIG 命令查看或设置配置项. 二.查看修改 1.查看配置 1.1.vi redis ...

  4. Spring 环境与profile(三)——利用maven的resources、filter和profile实现不同环境使用不同配置文件

    基本概念 profiles定义了各个环境的变量id filters中定义了变量配置文件的地址,其中地址中的环境变量就是上面profile中定义的值 resources中是定义哪些目录下的文件会被配置文 ...

  5. 为什么Java不能以返回值区分重载方法?

    读者可能会想:"在区分重载方法的时候,为什么只能以类名和方法的形参列表作为标准呢?能否考虑用方法的返回值来区分呢?" 比如下面两个方法,虽然他们有相同的名字和形式参数,但却很容易区 ...

  6. H5的canvas绘图技术

    canvas元素是HTML5中新添加的一个元素,该元素是HTML5中的一个亮点.Canvas元素就像一块画布,通过该元素自带的API结合JavaScript代码可以绘制各种图形和图像以及动画效果. 1 ...

  7. highchart

    highchart 1 2 #下载 https://www.highcharts.com/download a. 简单例子 <!DOCTYPE html> <html lang=&q ...

  8. 2018 6年iOS开发常用的三方库

    开发一般APP必备三方库,省力秘籍!!!本篇文章会经常更新最新常用的三方. 1.网络请求库 AFNetworking https://github.com/AFNetworking/AFNetwork ...

  9. 1024MySQL事物提交机制

    转自 http://www.cnblogs.com/exceptioneye/p/5451960.html MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提 ...

  10. [LeetCode] Sliding Window Median 滑动窗口中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...