• Libuv源码解析 - async


    Libuv源码解析 - async

    uv_async_init

    int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
      uv_req_t* req;
    
      //初始化handle句柄
      uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC);
      //初始化除handle公共结构之外的async属性
      handle->async_sent = 0;           //默认对应的事件未触发,初始化标记位
      handle->async_cb = async_cb;      //初始化异步事件触发时执行的回调事件
    
      req = &handle->async_req;
      //初始化uv_req_s结构,该结构记录I/O完成端口操作
      UV_REQ_INIT(req, UV_WAKEUP);
      req->data = handle;
    
      //设置handle状态为活跃状态,并将loop的活跃句柄个数加一
      uv__handle_start(handle);
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    uv_async_send

    //外部调用该函数就可以触发一次事件,就好像唤醒一个线程一样。这个函数是线程安全的,同时
    //也有一个特性:针对一个请求对象,多次调用时只保证至少触发一次,就好像Windows的消息循环
    //将同类消息合并一样。
    int uv_async_send(uv_async_t* handle) {
      uv_loop_t* loop = handle->loop;
    
      if (handle->type != UV_ASYNC) {
        /* Can't set errno because that's not thread-safe. */
        return -1;
      }
    
      /* The user should make sure never to call uv_async_send to a closing or
       * closed handle. */
      assert(!(handle->flags & UV_HANDLE_CLOSING));
    
      //用cas原语做了一次锁判断,持有锁的发送一个请求。
      //那么uv_async_send就可以这么理解:它是线程安全的,发送请求会置位async_sent
      //在async_sent没有被复位之前,后续请求都会被忽略
      if (!uv__atomic_exchange_set(&handle->async_sent)) {
        //使用重叠结构发送一个iocp请求,最终触发事件由GetCompletionStatus处理,
        POST_COMPLETION_FOR_REQ(loop, &handle->async_req);
      }
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    uv_process_async_wakeup_req

    //调用回调事件并复位async_sent
    void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
        uv_req_t* req) {
      assert(handle->type == UV_ASYNC);
      assert(req->type == UV_WAKEUP);
    
      handle->async_sent = 0;
    
      if (handle->flags & UV_HANDLE_CLOSING) {
        //销毁处理,加入到endgame队列中,可以调用uv_async_close或uv_close进行触发
        uv_want_endgame(loop, (uv_handle_t*)handle); 
      } else if (handle->async_cb != NULL) {
        handle->async_cb(handle);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    26、特殊的Sql执行1(使用${}也可以使用#)模糊查询
    MySQL InnoDB 引擎底层解析(二)
    教师教学质量评价管理系统(ASP.net+SqlServer)
    【毕业设计】stm32机器视觉的人脸识别系统 - 单片机 物联网 嵌入式
    VSCode 居然是个娱乐软件?让你 high 到爆的几款插件
    Ubuntu下安装Scala
    金融期货账号怎么开?
    SAP SEGW 事物码里的 ABAP 类型和 EDM 类型映射的一个具体例子
    【python3】5.正则表达式
    医疗机械公司网站网页
  • 原文地址:https://blog.csdn.net/qq135595696/article/details/127955022