libuv Timer 模块

Timer handles are used to schedule callbacks to be called in the future.

libuv的Timer模块的实现还是相对简单的,对libuv的解析就从Timer模块开始。

数据结构


Timer模块的Handle Type(这里可以理解为Timer实例的数据结构)是uv_timer_s,其内容如下:

struct uv_timer_s {
    UV_HANDLE_FIELDS
    UV_TIMER_PRIVATE_FIELDS
};

#define UV_TIMER_PRIVATE_FIELDS                           
  uv_timer_cb timer_cb;    #timer到期时的回调函数                                         
  void* heap_node[3];      #用于维护timer的最小堆    
  uint64_t timeout;        #timer的超时时间,其实是到多长时间后timer被触发       
  uint64_t repeat;         #timer是否重复                                                 
  uint64_t start_id;

接口


1. uv_timer_init

uv_timer_init接口的实现很简单。

# file: timer.c
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
    uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);   [1]
    handle->timer_cb = NULL;
    handle->repeat = 0;
    return 0;
}

代码[1]对uv_handle_t进行了初始化。来看一下uv__handle_init宏定义。

#define uv__handle_init(loop_, h, type_)                                    
    do {                                                                        
        (h)->loop = (loop_);                                                   
        (h)->type = (type_);                                                  
        (h)->flags = UV__HANDLE_REF;  
        QUEUE_INSERT_TAIL(&(loop_)->handle_queue, &(h)->handle_queue); [1]
        uv__handle_platform_init(h);                                             
    }                                                                           
    while (0)

其中最关键的部分是将h(uv_handle_t)加入loop->handle_queue的队列中去。

2. uv_timer_start

uv_timer_start接口的主要任务就是将uv_timer_t这个handler加入loop维护的一个最小堆中(timer_heap)

int uv_timer_start(uv_timer_t* handle,
               uv_timer_cb cb,
               uint64_t timeout,
               uint64_t repeat) {
    uint64_t clamped_timeout;

    if (cb == NULL)
        return -EINVAL;

    if (uv__is_active(handle))
        uv_timer_stop(handle);

     ......
     heap_insert((struct heap*) &handle->loop->timer_heap,
          (struct heap_node*) &handle->heap_node,
          timer_less_than);
     uv__handle_start(handle);

      return 0;
}

3.uv_timer_stop

uv_timer_stop做的事情更简单了,他将Timer中timer_heap中删除掉并关闭handler。

小结


libuv里面Timer是非常简单的模块了,