您的位置:首页 > Web前端 > Node.js

Nodejs事件引擎libuv源码剖析之:请求(request)结构的设计剖析

2017-06-29 00:00 197 查看

前言

在libuv中,请求(request)代表一个用户向libuv发出的指令,比如uv_connect_s就表示一个tcp的连接请求、uv_work_s代表要递交给libuv线程池执行的任务请求、uv_write_s代表一个写请求。

类似于上一篇讲句柄(handle)那样,请求也由一个抽象基类和相应的子类组成,这个基类就是uv_req_s,下面来看一下它的定义:

/* Abstract base class of all requests. */
struct uv_req_s {
/* public */                                                                \
void* data;                                                                 \
/* read-only */                                                             \
uv_req_type type;                                                           \
/* private */                                                               \
void* active_queue[2];                                                      \
void* reserved[4];                                                          \
};

其中,data可以用来携带任何类型的用户数据;type为该请求的类型,其取值可以为:

typedef enum {
UV_UNKNOWN_REQ = 0,
UV_REQ,
UV_CONNECT,
UV_WRITE,
UV_SHUTDOWN,
UV_UDP_SEND,
UV_FS,
UV_WORK,
UV_GETADDRINFO,
UV_GETNAMEINFO,
UV_REQ_TYPE_PRIVATE,
UV_REQ_TYPE_MAX,
} uv_req_type;

active_queue是一个队列节点,该请求会通过该节点将自己挂载到所绑定的loop中的active_reqs队列上;该操作(添加、删除)主要通过uv__req_register和uv__req_unregister两个宏定义实现:

#define uv__req_register(loop, req)                                           \
do {                                                                        \
QUEUE_INSERT_TAIL(&(loop)->active_reqs, &(req)->active_queue);            \
}                                                                           \
while (0)

#define uv__req_unregister(loop, req)                                         \
do {                                                                        \
assert(uv__has_active_reqs(loop));                                        \
QUEUE_REMOVE(&(req)->active_queue);                                       \
}                                                                           \
while (0)

用户并不会直接使用以上两个宏,而是会使用uv__req_init来初始化一个请求,该函数实现如下:

void uv__req_init(uv_loop_t* loop,
uv_req_t* req,
uv_req_type type) {
uv_req_init(loop, req);
req->type = type;
uv__req_register(loop, req);//注册这个req
}

请求并不会单独被处理,一个请求除了会被挂载在loop->active_reqs上,每个req都会被赋值给相应的句柄中的成员。下面画图libuv中各个请求中的关系,其中横线以上的为抽象基类,横线以下都是uv_req_t的直接子类。



系列文章

Nodejs事件引擎libuv源码剖析之:高效队列(queue)的实现

Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

Nodejs事件引擎libuv源码剖析之:句柄(handle)结构的设计剖析

Nodejs事件引擎libuv源码剖析之:请求(request)结构的设计剖析

Nodejs事件引擎libuv源码剖析之:事件循环(loop)结构的设计剖析

Nodejs事件引擎libuv源码剖析之:跨平台系统调用(syscall)实现原理

Nodejs事件引擎libuv源码剖析之:文件(fs)实现原理

Nodejs事件引擎libuv源码剖析之:管道(pipe)实现原理

Nodejs事件引擎libuv源码剖析之:网络(net)实现原理

Nodejs事件引擎libuv源码剖析之:定时器(timer)实现原理
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  libuv源码 请求