huenchao / libuv-study-v1.x

libuv源码阅读的注释版本
Other
2 stars 0 forks source link

看一眼prepare怎么跑的? #10

Open huenchao opened 4 years ago

huenchao commented 4 years ago

本文例子是test-loop-stop.c


#include "uv.h"
#include "task.h"

static uv_prepare_t prepare_handle;
static uv_timer_t timer_handle;
static int prepare_called = 0;
static int timer_called = 0;
static int num_ticks = 10;

static void prepare_cb(uv_prepare_t* handle) {
  ASSERT(handle == &prepare_handle);
  prepare_called++;
  if (prepare_called == num_ticks)
    uv_prepare_stop(handle);
}

static void timer_cb(uv_timer_t* handle) {
  ASSERT(handle == &timer_handle);
  timer_called++;
  if (timer_called == 1)
    uv_stop(uv_default_loop());
  else if (timer_called == num_ticks)
    uv_timer_stop(handle);
}

TEST_IMPL(loop_stop) {
  int r;
  uv_prepare_init(uv_default_loop(), &prepare_handle);
  uv_prepare_start(&prepare_handle, prepare_cb);
  uv_timer_init(uv_default_loop(), &timer_handle);
  uv_timer_start(&timer_handle, timer_cb, 100, 100);

  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
  ASSERT(r != 0);
  ASSERT(timer_called == 1);

  r = uv_run(uv_default_loop(), UV_RUN_NOWAIT);
  ASSERT(r != 0);
  ASSERT(prepare_called > 1);

  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
  ASSERT(r == 0);
  ASSERT(timer_called == 10);
  ASSERT(prepare_called == 10);

  return 0;
}
huenchao commented 4 years ago

我们先打上3个断点: 3C73D9A2-55E6-4B9A-B78F-CCF0457AC166

huenchao commented 4 years ago

1: 第1和第2个断点,初始化了static uv_loop_t default_loop_structprepare_handle,具体可以参考timer的过程,就是handle和loop相互关联。与timer不同的是,它更简单~ 因为不涉及最小堆的处理,直接就是queue的关联,还有cb的初始化。

2.直接进入uv_run(uv_default_loop(), UV_RUN_DEFAULT);uv__run_prepare(loop);处打上断点。如图: image

我们发现里面是个宏定义,不影响,看代码: image

QUEUE_MOVE(&loop->name##_handles, &queue);就是把 &loop->name##_handles从队列里删除,把&queue加进去。 然后while循环,就是一直消费prepare队列里的节点,