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. linux下面的打包压缩命令

    tar命令 tar [-cxtzjvfpPN] 文件与目录 ....linux下面压缩之前要把一堆文件打个包再压缩,即使只有一个文件也需要打个包.例子:tar czvf 1.tar.gz hello. ...

  2. 爬虫模块BeautifulSoup

    中文文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html# 1.1      安装BeautifulSoup模块 ...

  3. 使用java 打印日历

    package hangshu; /* * 打印从1900年到2.year年的日历 */ import java.util.Scanner; public class Calender { publi ...

  4. 转:java中Vector的使用

    转:https://www.cnblogs.com/zhaoyan001/p/6077492.html Vector 可实现自动增长的对象数组. java.util.vector提供了向量类(vect ...

  5. SQL 中的日期和时间类型

    在我们SQL中一般支持三种数据类型. date:日历日期,包括年(四位),月和日. time: 一天中的时间,包括小时,分和秒.可以用变量time(p)来表示秒的小数点后的数字位数(默认是0). 通过 ...

  6. 前端学习之jquery/下

    前端学习之jquery 一 属性操作 html(): console.log($("div").html()); $(".test").html("& ...

  7. mysql 练习题

    导出现有数据库数据: C:\Users\Administrator>mysqldump -u root db1>D:\agon\db1.sql -p  #结构+数据 mysqldump - ...

  8. Text-文本检查

    #检查文本 from tkinter import * import hashlib master=Tk() text = Text(master,width=30,height=5) text.pa ...

  9. angularjs中的run()方法使用

    run方法用于初始化全局的数据,仅对全局作用域起作用. 举个栗子吧:<script type="text/javascript"> var m1 = angular.m ...

  10. Java中的变量数据类型补充

    Java中变量的数据类型的补充 变量按照数据类型进行分类 1.基本数据类型 数值型:①整数类型(byte,short,int,long)②浮点型(float,doubbe)③字符型(char)④布尔型 ...