event loop核心代码(libuv)

int uv_run(uv_loop_t * loop, uv_run_mode mode) {

  int timeout;
  int r;
  int ran_pending;

  // 从uv__loop_alive中我们知道event loop继续的条件是以下三者之一:
  // 1,有活跃的handles(libuv定义handle就是一些long-lived objects,例如tcp server这样)     
  // 2,有活跃的request     
  // 3,loop中的closing_handles
  r = uv__loop_alive(loop);
  if (!r) uv__update_time(loop);

  while (r != 0 && loop -> stop_flag == 0) {
    // 更新时间变量,这个变量在uv__run_timers中会用到
    uv__update_time(loop);
    // timers阶段
    uv__run_timers(loop);
    // 从libuv的文档中可知,这个其实就是I/O callback阶段,ran_pending指示队列是否为空
    ran_pending = uv__run_pending(loop);
    // idle阶段
    uv__run_idle(loop);
    // prepare阶段
    uv__run_prepare(loop);
    // 设置poll阶段的超时时间,以下几种情况下超时会被设为0,这意味着此时poll阶段不会被阻塞,在下面的poll阶段我们还会详细讨论这个       
    // 1,stop_flag不为0       
    // 2,没有活跃的handles和request       
    // 3,idle、I/O callback、close阶段的handle队列不为空       
    // 否则,设为timer阶段的callback队列中,距离当前时间最近的那个
    timeout = 0;
    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) {
      timeout = uv_backend_timeout(loop);
    }
    // poll阶段
    uv__io_poll(loop, timeout);
    // check阶段
    uv__run_check(loop);
    // close阶段
    uv__run_closing_handles(loop);
    // 如果mode == UV_RUN_ONCE(意味着流程继续向前)时,在所有阶段结束后还会检查一次timers,这个的逻辑的原因不太明确              
    if (mode == UV_RUN_ONCE) {
      uv__update_time(loop);
      uv__run_timers(loop);
    }

    r = uv__loop_alive(loop);

    if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT) {
      break;
    }
  }

  if (loop -> stop_flag != 0) {
    loop -> stop_flag = 0;
  }

  return r;
  
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值