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

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

2013-06-04 |

代码如下

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
26
27
28
29
30
31
32
33
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);

需要关注的是

1
2
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, 编码技巧

| 标签: