首页 > 代码库 > Nodejs事件引擎libuv源码剖析之:请求(request)结构的设计剖析
Nodejs事件引擎libuv源码剖析之:请求(request)结构的设计剖析
声明:本文为原创博文,转载请注明出处。
在libuv中,请求(request)代表一个用户向libuv发出的指令,比如uv_connect_s就表示一个tcp的连接请求、uv_work_s代表要递交给libuv线程池执行的任务请求、uv_write_s代表一个写请求。
类似于上一篇讲句柄(handle)那样,请求也由一个抽象基类和相应的子类组成,这个基类就是uv_req_s,下面来看一下它的定义:
1 /* Abstract base class of all requests. */ 2 struct uv_req_s { 3 /* public */ 4 void* data; 5 /* read-only */ 6 uv_req_type type; 7 /* private */ 8 void* active_queue[2]; 9 void* reserved[4]; 10 };
其中,data可以用来携带任何类型的用户数据;type为该请求的类型,其取值可以为:
1 typedef enum { 2 UV_UNKNOWN_REQ = 0, 3 UV_REQ, 4 UV_CONNECT, 5 UV_WRITE, 6 UV_SHUTDOWN, 7 UV_UDP_SEND, 8 UV_FS, 9 UV_WORK, 10 UV_GETADDRINFO, 11 UV_GETNAMEINFO, 12 UV_REQ_TYPE_PRIVATE, 13 UV_REQ_TYPE_MAX, 14 } uv_req_type;
active_queue是一个队列节点,该请求会通过该节点将自己挂载到所绑定的loop中的active_reqs队列上;该操作(添加、删除)主要通过uv__req_register和uv__req_unregister两个宏定义实现:
1 #define uv__req_register(loop, req) 2 do { 3 QUEUE_INSERT_TAIL(&(loop)->active_reqs, &(req)->active_queue); 4 } 5 while (0) 6 7 #define uv__req_unregister(loop, req) 8 do { 9 assert(uv__has_active_reqs(loop)); 10 QUEUE_REMOVE(&(req)->active_queue); 11 } 12 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源码剖析之:请求(request)结构的设计剖析
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。