libuv学习笔记(4)

libuv学习笔记(4)

uv_req_t 基本请求的定义以及相关函数

结构体定义

与uv_handlt_t结构体类似,将通用的数据结构定义为UV_REQ_FIELDS宏,每种类型的请求都在相同位置(开始)包含该宏,所以任何req类型的指针都能转换为uv_req_t*,实现了类似继承的效果。

typedef struct uv_req_s uv_req_t;
struct uv_req_s 
{
  //UV_REQ_FIELDS宏展开:
  /* 指向用户自定义数据 */                                                       
  void* data;                                                                
  /* 请求类型,只读 */                                                           
  uv_req_type type;                                                           
  /* 私有数据 */                                                               
  void* active_queue[2];                                                     
  void* reserved[4];                                                         
  //UV_REQ_PRIVATE_FIELDS 宏展开(在uv-win.h中定义,平台相关) :                                            
  union {                                                                    
    /* i/o操作,iocp用到 */                                              
    struct {                                                                 
      OVERLAPPED overlapped;                                                
      size_t queued_bytes;                                                  
    } io;                                                                   
  } u;                                                                      
  struct uv_req_s* next_req;//指向下一个请求
};

请求类型包括(宏展开后):

typedef enum {
  UV_UNKNOWN_REQ = 0,

  UV_REQ,
  UV_CONNECT,//连接
  UV_WRITE,//写
  UV_SHUTDOWN,//关闭
  UV_UDP_SEND,//发送udp数据
  UV_FS,//文件操作
  UV_WORK,//在线程池中运行
  UV_GETADDRINFO,//获取地址
  UV_GETNAMEINFO,//获取主机名

  //内部请求类型
  UV_ACCPTE,//接受连接
  UV_FS_EVENT_REQ,  //文件事件                                                          
  UV_POLL_REQ, //轮询                                                  
  UV_PROCESS_EXIT, //关闭进程                                                           
  UV_READ,//读取                                                   
  UV_UDP_RECV, //udp socket接收数据                                                               
  UV_WAKEUP, //                                                                 
  UV_SIGNAL_REQ,//信号
  UV_REQ_TYPE_MAX
} uv_req_type;

相关函数

1.取消请求,导出函数,uv.h中声明,threadpool.c中定义
int uv_cancel(uv_req_t* req) 
{
  struct uv__work* wreq;
  uv_loop_t* loop;
  //根据请求类型获取对应的请求指针,只支持取消通过线程池处理的请求(4类)
  switch (req->type) {
  case UV_FS:
    loop =  ((uv_fs_t*) req)->loop;
    wreq = &((uv_fs_t*) req)->work_req;
    break;
  case UV_GETADDRINFO:
    loop =  ((uv_getaddrinfo_t*) req)->loop;
    wreq = &((uv_getaddrinfo_t*) req)->work_req;
    break;
  case UV_GETNAMEINFO:
    loop = ((uv_getnameinfo_t*) req)->loop;
    wreq = &((uv_getnameinfo_t*) req)->work_req;
    break;
  case UV_WORK:
    loop =  ((uv_work_t*) req)->loop;
    wreq = &((uv_work_t*) req)->work_req;
    break;
  default:
    return UV_EINVAL;
  }
  //调用内部函数
  return uv__work_cancel(loop, req, wreq);
}

内部函数 uv__work_cancel

static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) 
{
  int cancelled;
  //互斥量锁定(内部通过临界区实现),然后移除请求对象(req)的工作项(w)
  uv_mutex_lock(&mutex);
  uv_mutex_lock(&w->loop->wq_mutex);

  cancelled = !QUEUE_EMPTY(&w->wq) && w->work != NULL;
  if (cancelled)
    QUEUE_REMOVE(&w->wq);

  uv_mutex_unlock(&w->loop->wq_mutex);
  uv_mutex_unlock(&mutex);

  if (!cancelled)
    return UV_EBUSY;
  //工作函数设为uv__cancelled,后面loop会根据这个值判断请求是否是取消的(uv__work_done)
  w->work = uv__cancelled;
  uv_mutex_lock(&loop->wq_mutex);
  //将请求添加到loop的完成请求的列表
  QUEUE_INSERT_TAIL(&loop->wq, &w->wq);
  //发送异步消息,wakeup loop
  uv_async_send(&loop->wq_async);
  uv_mutex_unlock(&loop->wq_mutex);

  return 0;
}

不同类型的请求会有不同的API,将会在之后具体分析。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值