• 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的直接子类。 

  • 相关阅读:
    leetcode-832-Flipping an Image
    leetcode-830-Positions of Large Groups
    leetcode-824-Goat Latin(字符串的处理)
    leetcode-821-Shortest Distance to a Character
    leetcode-819-Most Common Word(词频统计)
    HDU 4729 An Easy Problem for Elfness(树链剖分边权+二分)
    python爬虫(1)——正则表达式
    利用MySQL之federated引擎实现DBLink功能
    HTTPS原理及流程
    NIO、多路复用的终极奥义
  • 原文地址:https://www.cnblogs.com/chenyangyao/p/libuv_req.html
Copyright © 2020-2023  润新知