Swoole源码学习记录(八)——Reactor模块-epoll

Swoole版本:1.7.5-stable

Github地址: https://github.com/LinkedDestiny/swoole-src-analysis

Reactor模块可以说是Swoole中最核心的模块之一,正是这些reactor模型为swoole提供了异步操作的基础。Swoole中根据不同的内核函数,提供了四种Reactor封装,ReactorEpoll,ReactorKqueue,ReactorPoll和ReactorSelect。同时,Swoole通过结构体swReactor封装了对于reactor的操作函数和基本属性。本章,我将分析swReactor以及四种Reactor模型中的ReactorEpoll,并回顾一下epoll的相关知识。

 

一.swReactor

swReactor结构体声明在swoole.h的698– 721行,其声明如下:

struct swReactor_s
{
         void *object;
         void *ptr; //reserve
         uint32_t event_num;
         uint32_t max_event_num;
         uint16_t id; //Reactor ID
         uint16_t flag; //flag
         char running;
 
         swReactor_handle handle[SW_MAX_FDTYPE];       //默认事件
         swReactor_handle write_handle[SW_MAX_FDTYPE]; //扩展事件1(一般为写事件)
         swReactor_handle error_handle[SW_MAX_FDTYPE]; //扩展事件2(一般为错误事件,如socket关闭)
 
         int (*add)(swReactor *, int fd, intfdtype);
         int (*set)(swReactor *, int fd, intfdtype);
         int (*del)(swReactor *, int fd);
         int (*wait)(swReactor *, struct timeval*);
         void (*free)(swReactor *);
         int (*setHandle)(swReactor *, intfdtype, swReactor_handle);
 
         void (*onTimeout)(swReactor *); //发生超时时
         void (*onFinish)(swReactor *);  //完成一次轮询
};
typedef struct swReactor_s swReactor;  // swoole.h 354行
typedef int (*swReactor_handle)(swReactor *reactor,swEvent *event); // swoole.h 355行

属性分析:object存放实际reactor模型的内存地址,reserve, event_num存放现有的事件数目,max_event_num存放允许持有的最大事件数目,id用于存放对应reactor的id,flag为标记位,running用于标记该reactor是否正在运行,接下来三个数组用于存放需要监听的事件的响应回调函数,余下的都是对应reactor的操作函数,这些函数将在具体的Reactor模型中被实现并赋值。

对应Reactor的部分通用的操作函数声明在swoole.h文件中827– 873行。首先是一个枚举类型SW_EVENTS,用于指定对应的事件id,声明如下:

enum SW_EVENTS
{
SW_EVENT_DEAULT= 256,
SW_EVENT_READ= 1u << 9,
SW_EVENT_WRITE= 1u << 10,
SW_EVENT_ERROR= 1u << 11,
};


SW_EVENTS中指定了四种事件类型:DEFAULT代表默认事件,READ和WRITE分别代表读写事件,ERROR代表错误。

接着是四个操作事件类型的函数:

// 过滤fdtype中的读、写、错误事件标记
static sw_inline int swReactor_fdtype(int fdtype)
{
return fdtype & (~SW_EVENT_READ) &(~SW_EVENT_WRITE) & (~SW_EVENT_ERROR);
}
         //判定是否为读事件和其他swFd_type类型的监听
static sw_inline int swReactor_event_read(int fdtype)
{
return (fdtype < SW_EVENT_DEAULT) || (fdtype &SW_EVENT_READ);
}
         //判定是否为事件监听
static sw_inline int swReactor_event_write(int fdtype)
{
return fdtype & SW_EVENT_WRITE;
}
         //判定是否为错误事件监听
static sw_inlineint swReactor_event_error(int fdtype)
{
return fdtype & SW_EVENT_ERROR;
}

接着是四个个通用操作函数,函数声明如下:

int swReactor_auto(swReactor *reactor, int max_event);
int swReactor_receive(swReactor *reactor, swEvent *event);
int swReactor_setHandle(swReactor *, int,swReactor_handle);
swReactor_handle swReactor_getHandle(swReactor *reactor,int event_type, int fdtype);

这四个函数分别用于自动创建可用类型的reactor模型、从reactor接收到的swEvent中读取数据、设置Reactor的回调函数、获得Reactor的回调函数。函数的具体声明在

你可能感兴趣的:(swoole,PHP,swoole,服务器,源码)