glusterfs c语言api,glusterfs 4.0.1 event模块 分析笔记1

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个表格,每个表格里有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 模型的实现

在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,

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值