您当前位置: 首页 » 编码技巧 » win » 编码技巧 » [chromium]MessageLoopProxyTest单元测试中的一个隐蔽问题

[chromium]MessageLoopProxyTest单元测试中的一个隐蔽问题

2013-06-04 |

代码如下

  MessageLoop* task_run_on = NULL;
  MessageLoop* task_deleted_on = NULL;
  int task_delete_order = -1;
  MessageLoop* reply_run_on = NULL;
  MessageLoop* reply_deleted_on = NULL;
  int reply_delete_order = -1;

  scoped_refptr task_recoder =
      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
  scoped_refptr reply_recoder =
      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);

  ASSERT_TRUE(task_thread_.message_loop_proxy()->PostTaskAndReply(
      FROM_HERE,
      Bind(&RecordLoop, task_recoder),
      Bind(&RecordLoopAndQuit, reply_recoder)));

  // Die if base::Bind doesn't retain a reference to the recorders.
  task_recoder = NULL;
  reply_recoder = NULL;
  ASSERT_FALSE(task_deleted_on);
  ASSERT_FALSE(reply_deleted_on);

  //--- 这里将是比较关键的一个问题 begin ---
  UnblockTaskThread();
  current_loop_->Run();
  //--- 这里将是比较关键的一个问题 end ---

  EXPECT_EQ(task_thread_.message_loop(), task_run_on);
  EXPECT_EQ(current_loop_.get(), task_deleted_on);
  EXPECT_EQ(current_loop_.get(), reply_run_on);
  EXPECT_EQ(current_loop_.get(), reply_deleted_on);
  EXPECT_LT(task_delete_order, reply_delete_order);

需要关注的是

  UnblockTaskThread();
  current_loop_->Run();

这个单元测试实际上是创建了2个消息循环。
Thread 内部本身就有一个MessageLoop
外上current_loop_ 自身也是MessageLoop

task_thread_在启动以后,一直在等待一个事件。直到调用了UnblockTaskThread();
之后事件被激活task_thread_被激活进行处理。

如果这里不做调用current_loop_->Run();可能会出现由于任务调度导致task_thread_来没有来记得处理完一轮Loop,整个单元测试测试就结束了。

同时,由于PostTaskAndReply这种类型的消息抛送。会将托管调用的返回信息,通过消息抛送的方式,返回到掉调用该函数的线程消息循环中。

因此,在这里current_loop_->Run();
在这里有2个作用:

1,通过线程调度,让task_thread_拥有足够的时间去执行完消息循环
2,等待返回信息返回过来

分类:

win, 编码技巧

| 标签: