OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <vector> | 5 #include <vector> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/pending_task.h" | 13 #include "base/pending_task.h" |
14 #include "base/posix/eintr_wrapper.h" | 14 #include "base/posix/eintr_wrapper.h" |
15 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
16 #include "base/thread_task_runner_handle.h" | 16 #include "base/thread_task_runner_handle.h" |
17 #include "base/threading/platform_thread.h" | 17 #include "base/threading/platform_thread.h" |
18 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
20 | 20 |
21 #if defined(OS_WIN) | 21 #if defined(OS_WIN) |
22 #include "base/message_pump_win.h" | 22 #include "base/message_pump_win.h" |
23 #include "base/win/scoped_handle.h" | 23 #include "base/win/scoped_handle.h" |
24 #endif | 24 #endif |
25 | 25 |
26 using base::PlatformThread; | 26 namespace base { |
27 using base::Thread; | |
28 using base::Time; | |
29 using base::TimeDelta; | |
30 using base::TimeTicks; | |
31 | 27 |
32 // TODO(darin): Platform-specific MessageLoop tests should be grouped together | 28 // TODO(darin): Platform-specific MessageLoop tests should be grouped together |
33 // to avoid chopping this file up with so many #ifdefs. | 29 // to avoid chopping this file up with so many #ifdefs. |
34 | 30 |
35 namespace { | 31 namespace { |
36 | 32 |
37 class Foo : public base::RefCounted<Foo> { | 33 class Foo : public RefCounted<Foo> { |
38 public: | 34 public: |
39 Foo() : test_count_(0) { | 35 Foo() : test_count_(0) { |
40 } | 36 } |
41 | 37 |
42 void Test0() { | 38 void Test0() { |
43 ++test_count_; | 39 ++test_count_; |
44 } | 40 } |
45 | 41 |
46 void Test1ConstRef(const std::string& a) { | 42 void Test1ConstRef(const std::string& a) { |
47 ++test_count_; | 43 ++test_count_; |
(...skipping 18 matching lines...) Expand all Loading... |
66 void Test2Mixed(const std::string& a, std::string* b) { | 62 void Test2Mixed(const std::string& a, std::string* b) { |
67 ++test_count_; | 63 ++test_count_; |
68 result_.append(a); | 64 result_.append(a); |
69 result_.append(*b); | 65 result_.append(*b); |
70 } | 66 } |
71 | 67 |
72 int test_count() const { return test_count_; } | 68 int test_count() const { return test_count_; } |
73 const std::string& result() const { return result_; } | 69 const std::string& result() const { return result_; } |
74 | 70 |
75 private: | 71 private: |
76 friend class base::RefCounted<Foo>; | 72 friend class RefCounted<Foo>; |
77 | 73 |
78 ~Foo() {} | 74 ~Foo() {} |
79 | 75 |
80 int test_count_; | 76 int test_count_; |
81 std::string result_; | 77 std::string result_; |
82 }; | 78 }; |
83 | 79 |
84 void RunTest_PostTask(MessageLoop::Type message_loop_type) { | 80 void RunTest_PostTask(MessageLoop::Type message_loop_type) { |
85 MessageLoop loop(message_loop_type); | 81 MessageLoop loop(message_loop_type); |
86 | 82 |
87 // Add tests to message loop | 83 // Add tests to message loop |
88 scoped_refptr<Foo> foo(new Foo()); | 84 scoped_refptr<Foo> foo(new Foo()); |
89 std::string a("a"), b("b"), c("c"), d("d"); | 85 std::string a("a"), b("b"), c("c"), d("d"); |
90 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 86 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
91 &Foo::Test0, foo.get())); | 87 &Foo::Test0, foo.get())); |
92 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 88 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
93 &Foo::Test1ConstRef, foo.get(), a)); | 89 &Foo::Test1ConstRef, foo.get(), a)); |
94 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 90 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
95 &Foo::Test1Ptr, foo.get(), &b)); | 91 &Foo::Test1Ptr, foo.get(), &b)); |
96 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 92 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
97 &Foo::Test1Int, foo.get(), 100)); | 93 &Foo::Test1Int, foo.get(), 100)); |
98 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 94 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
99 &Foo::Test2Ptr, foo.get(), &a, &c)); | 95 &Foo::Test2Ptr, foo.get(), &a, &c)); |
100 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 96 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
101 &Foo::Test2Mixed, foo.get(), a, &d)); | 97 &Foo::Test2Mixed, foo.get(), a, &d)); |
102 | 98 |
103 // After all tests, post a message that will shut down the message loop | 99 // After all tests, post a message that will shut down the message loop |
104 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 100 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
105 &MessageLoop::Quit, base::Unretained(MessageLoop::current()))); | 101 &MessageLoop::Quit, Unretained(MessageLoop::current()))); |
106 | 102 |
107 // Now kick things off | 103 // Now kick things off |
108 MessageLoop::current()->Run(); | 104 MessageLoop::current()->Run(); |
109 | 105 |
110 EXPECT_EQ(foo->test_count(), 105); | 106 EXPECT_EQ(foo->test_count(), 105); |
111 EXPECT_EQ(foo->result(), "abacad"); | 107 EXPECT_EQ(foo->result(), "abacad"); |
112 } | 108 } |
113 | 109 |
114 void RunTest_PostTask_SEH(MessageLoop::Type message_loop_type) { | 110 void RunTest_PostTask_SEH(MessageLoop::Type message_loop_type) { |
115 MessageLoop loop(message_loop_type); | 111 MessageLoop loop(message_loop_type); |
116 | 112 |
117 // Add tests to message loop | 113 // Add tests to message loop |
118 scoped_refptr<Foo> foo(new Foo()); | 114 scoped_refptr<Foo> foo(new Foo()); |
119 std::string a("a"), b("b"), c("c"), d("d"); | 115 std::string a("a"), b("b"), c("c"), d("d"); |
120 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 116 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
121 &Foo::Test0, foo.get())); | 117 &Foo::Test0, foo.get())); |
122 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 118 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
123 &Foo::Test1ConstRef, foo.get(), a)); | 119 &Foo::Test1ConstRef, foo.get(), a)); |
124 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 120 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
125 &Foo::Test1Ptr, foo.get(), &b)); | 121 &Foo::Test1Ptr, foo.get(), &b)); |
126 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 122 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
127 &Foo::Test1Int, foo.get(), 100)); | 123 &Foo::Test1Int, foo.get(), 100)); |
128 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 124 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
129 &Foo::Test2Ptr, foo.get(), &a, &c)); | 125 &Foo::Test2Ptr, foo.get(), &a, &c)); |
130 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 126 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
131 &Foo::Test2Mixed, foo.get(), a, &d)); | 127 &Foo::Test2Mixed, foo.get(), a, &d)); |
132 | 128 |
133 // After all tests, post a message that will shut down the message loop | 129 // After all tests, post a message that will shut down the message loop |
134 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 130 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
135 &MessageLoop::Quit, base::Unretained(MessageLoop::current()))); | 131 &MessageLoop::Quit, Unretained(MessageLoop::current()))); |
136 | 132 |
137 // Now kick things off with the SEH block active. | 133 // Now kick things off with the SEH block active. |
138 MessageLoop::current()->set_exception_restoration(true); | 134 MessageLoop::current()->set_exception_restoration(true); |
139 MessageLoop::current()->Run(); | 135 MessageLoop::current()->Run(); |
140 MessageLoop::current()->set_exception_restoration(false); | 136 MessageLoop::current()->set_exception_restoration(false); |
141 | 137 |
142 EXPECT_EQ(foo->test_count(), 105); | 138 EXPECT_EQ(foo->test_count(), 105); |
143 EXPECT_EQ(foo->result(), "abacad"); | 139 EXPECT_EQ(foo->result(), "abacad"); |
144 } | 140 } |
145 | 141 |
(...skipping 19 matching lines...) Expand all Loading... |
165 MessageLoop loop(message_loop_type); | 161 MessageLoop loop(message_loop_type); |
166 | 162 |
167 // Test that PostDelayedTask results in a delayed task. | 163 // Test that PostDelayedTask results in a delayed task. |
168 | 164 |
169 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); | 165 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); |
170 | 166 |
171 int num_tasks = 1; | 167 int num_tasks = 1; |
172 Time run_time; | 168 Time run_time; |
173 | 169 |
174 loop.PostDelayedTask( | 170 loop.PostDelayedTask( |
175 FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks), | 171 FROM_HERE, Bind(&RecordRunTimeFunc, &run_time, &num_tasks), |
176 kDelay); | 172 kDelay); |
177 | 173 |
178 Time time_before_run = Time::Now(); | 174 Time time_before_run = Time::Now(); |
179 loop.Run(); | 175 loop.Run(); |
180 Time time_after_run = Time::Now(); | 176 Time time_after_run = Time::Now(); |
181 | 177 |
182 EXPECT_EQ(0, num_tasks); | 178 EXPECT_EQ(0, num_tasks); |
183 EXPECT_LT(kDelay, time_after_run - time_before_run); | 179 EXPECT_LT(kDelay, time_after_run - time_before_run); |
184 } | 180 } |
185 | 181 |
186 void RunTest_PostDelayedTask_InDelayOrder( | 182 void RunTest_PostDelayedTask_InDelayOrder( |
187 MessageLoop::Type message_loop_type) { | 183 MessageLoop::Type message_loop_type) { |
188 MessageLoop loop(message_loop_type); | 184 MessageLoop loop(message_loop_type); |
189 | 185 |
190 // Test that two tasks with different delays run in the right order. | 186 // Test that two tasks with different delays run in the right order. |
191 int num_tasks = 2; | 187 int num_tasks = 2; |
192 Time run_time1, run_time2; | 188 Time run_time1, run_time2; |
193 | 189 |
194 loop.PostDelayedTask( | 190 loop.PostDelayedTask( |
195 FROM_HERE, | 191 FROM_HERE, |
196 base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), | 192 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), |
197 TimeDelta::FromMilliseconds(200)); | 193 TimeDelta::FromMilliseconds(200)); |
198 // If we get a large pause in execution (due to a context switch) here, this | 194 // If we get a large pause in execution (due to a context switch) here, this |
199 // test could fail. | 195 // test could fail. |
200 loop.PostDelayedTask( | 196 loop.PostDelayedTask( |
201 FROM_HERE, | 197 FROM_HERE, |
202 base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | 198 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), |
203 TimeDelta::FromMilliseconds(10)); | 199 TimeDelta::FromMilliseconds(10)); |
204 | 200 |
205 loop.Run(); | 201 loop.Run(); |
206 EXPECT_EQ(0, num_tasks); | 202 EXPECT_EQ(0, num_tasks); |
207 | 203 |
208 EXPECT_TRUE(run_time2 < run_time1); | 204 EXPECT_TRUE(run_time2 < run_time1); |
209 } | 205 } |
210 | 206 |
211 void RunTest_PostDelayedTask_InPostOrder( | 207 void RunTest_PostDelayedTask_InPostOrder( |
212 MessageLoop::Type message_loop_type) { | 208 MessageLoop::Type message_loop_type) { |
213 MessageLoop loop(message_loop_type); | 209 MessageLoop loop(message_loop_type); |
214 | 210 |
215 // Test that two tasks with the same delay run in the order in which they | 211 // Test that two tasks with the same delay run in the order in which they |
216 // were posted. | 212 // were posted. |
217 // | 213 // |
218 // NOTE: This is actually an approximate test since the API only takes a | 214 // NOTE: This is actually an approximate test since the API only takes a |
219 // "delay" parameter, so we are not exactly simulating two tasks that get | 215 // "delay" parameter, so we are not exactly simulating two tasks that get |
220 // posted at the exact same time. It would be nice if the API allowed us to | 216 // posted at the exact same time. It would be nice if the API allowed us to |
221 // specify the desired run time. | 217 // specify the desired run time. |
222 | 218 |
223 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); | 219 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); |
224 | 220 |
225 int num_tasks = 2; | 221 int num_tasks = 2; |
226 Time run_time1, run_time2; | 222 Time run_time1, run_time2; |
227 | 223 |
228 loop.PostDelayedTask( | 224 loop.PostDelayedTask( |
229 FROM_HERE, | 225 FROM_HERE, |
230 base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), kDelay); | 226 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), kDelay); |
231 loop.PostDelayedTask( | 227 loop.PostDelayedTask( |
232 FROM_HERE, | 228 FROM_HERE, |
233 base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), kDelay); | 229 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), kDelay); |
234 | 230 |
235 loop.Run(); | 231 loop.Run(); |
236 EXPECT_EQ(0, num_tasks); | 232 EXPECT_EQ(0, num_tasks); |
237 | 233 |
238 EXPECT_TRUE(run_time1 < run_time2); | 234 EXPECT_TRUE(run_time1 < run_time2); |
239 } | 235 } |
240 | 236 |
241 void RunTest_PostDelayedTask_InPostOrder_2( | 237 void RunTest_PostDelayedTask_InPostOrder_2( |
242 MessageLoop::Type message_loop_type) { | 238 MessageLoop::Type message_loop_type) { |
243 MessageLoop loop(message_loop_type); | 239 MessageLoop loop(message_loop_type); |
244 | 240 |
245 // Test that a delayed task still runs after a normal tasks even if the | 241 // Test that a delayed task still runs after a normal tasks even if the |
246 // normal tasks take a long time to run. | 242 // normal tasks take a long time to run. |
247 | 243 |
248 const TimeDelta kPause = TimeDelta::FromMilliseconds(50); | 244 const TimeDelta kPause = TimeDelta::FromMilliseconds(50); |
249 | 245 |
250 int num_tasks = 2; | 246 int num_tasks = 2; |
251 Time run_time; | 247 Time run_time; |
252 | 248 |
253 loop.PostTask(FROM_HERE, base::Bind(&SlowFunc, kPause, &num_tasks)); | 249 loop.PostTask(FROM_HERE, Bind(&SlowFunc, kPause, &num_tasks)); |
254 loop.PostDelayedTask( | 250 loop.PostDelayedTask( |
255 FROM_HERE, | 251 FROM_HERE, |
256 base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks), | 252 Bind(&RecordRunTimeFunc, &run_time, &num_tasks), |
257 TimeDelta::FromMilliseconds(10)); | 253 TimeDelta::FromMilliseconds(10)); |
258 | 254 |
259 Time time_before_run = Time::Now(); | 255 Time time_before_run = Time::Now(); |
260 loop.Run(); | 256 loop.Run(); |
261 Time time_after_run = Time::Now(); | 257 Time time_after_run = Time::Now(); |
262 | 258 |
263 EXPECT_EQ(0, num_tasks); | 259 EXPECT_EQ(0, num_tasks); |
264 | 260 |
265 EXPECT_LT(kPause, time_after_run - time_before_run); | 261 EXPECT_LT(kPause, time_after_run - time_before_run); |
266 } | 262 } |
267 | 263 |
268 void RunTest_PostDelayedTask_InPostOrder_3( | 264 void RunTest_PostDelayedTask_InPostOrder_3( |
269 MessageLoop::Type message_loop_type) { | 265 MessageLoop::Type message_loop_type) { |
270 MessageLoop loop(message_loop_type); | 266 MessageLoop loop(message_loop_type); |
271 | 267 |
272 // Test that a delayed task still runs after a pile of normal tasks. The key | 268 // Test that a delayed task still runs after a pile of normal tasks. The key |
273 // difference between this test and the previous one is that here we return | 269 // difference between this test and the previous one is that here we return |
274 // the MessageLoop a lot so we give the MessageLoop plenty of opportunities | 270 // the MessageLoop a lot so we give the MessageLoop plenty of opportunities |
275 // to maybe run the delayed task. It should know not to do so until the | 271 // to maybe run the delayed task. It should know not to do so until the |
276 // delayed task's delay has passed. | 272 // delayed task's delay has passed. |
277 | 273 |
278 int num_tasks = 11; | 274 int num_tasks = 11; |
279 Time run_time1, run_time2; | 275 Time run_time1, run_time2; |
280 | 276 |
281 // Clutter the ML with tasks. | 277 // Clutter the ML with tasks. |
282 for (int i = 1; i < num_tasks; ++i) | 278 for (int i = 1; i < num_tasks; ++i) |
283 loop.PostTask(FROM_HERE, | 279 loop.PostTask(FROM_HERE, |
284 base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks)); | 280 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks)); |
285 | 281 |
286 loop.PostDelayedTask( | 282 loop.PostDelayedTask( |
287 FROM_HERE, base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | 283 FROM_HERE, Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), |
288 TimeDelta::FromMilliseconds(1)); | 284 TimeDelta::FromMilliseconds(1)); |
289 | 285 |
290 loop.Run(); | 286 loop.Run(); |
291 EXPECT_EQ(0, num_tasks); | 287 EXPECT_EQ(0, num_tasks); |
292 | 288 |
293 EXPECT_TRUE(run_time2 > run_time1); | 289 EXPECT_TRUE(run_time2 > run_time1); |
294 } | 290 } |
295 | 291 |
296 void RunTest_PostDelayedTask_SharedTimer( | 292 void RunTest_PostDelayedTask_SharedTimer( |
297 MessageLoop::Type message_loop_type) { | 293 MessageLoop::Type message_loop_type) { |
298 MessageLoop loop(message_loop_type); | 294 MessageLoop loop(message_loop_type); |
299 | 295 |
300 // Test that the interval of the timer, used to run the next delayed task, is | 296 // Test that the interval of the timer, used to run the next delayed task, is |
301 // set to a value corresponding to when the next delayed task should run. | 297 // set to a value corresponding to when the next delayed task should run. |
302 | 298 |
303 // By setting num_tasks to 1, we ensure that the first task to run causes the | 299 // By setting num_tasks to 1, we ensure that the first task to run causes the |
304 // run loop to exit. | 300 // run loop to exit. |
305 int num_tasks = 1; | 301 int num_tasks = 1; |
306 Time run_time1, run_time2; | 302 Time run_time1, run_time2; |
307 | 303 |
308 loop.PostDelayedTask( | 304 loop.PostDelayedTask( |
309 FROM_HERE, | 305 FROM_HERE, |
310 base::Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), | 306 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), |
311 TimeDelta::FromSeconds(1000)); | 307 TimeDelta::FromSeconds(1000)); |
312 loop.PostDelayedTask( | 308 loop.PostDelayedTask( |
313 FROM_HERE, | 309 FROM_HERE, |
314 base::Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | 310 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), |
315 TimeDelta::FromMilliseconds(10)); | 311 TimeDelta::FromMilliseconds(10)); |
316 | 312 |
317 Time start_time = Time::Now(); | 313 Time start_time = Time::Now(); |
318 | 314 |
319 loop.Run(); | 315 loop.Run(); |
320 EXPECT_EQ(0, num_tasks); | 316 EXPECT_EQ(0, num_tasks); |
321 | 317 |
322 // Ensure that we ran in far less time than the slower timer. | 318 // Ensure that we ran in far less time than the slower timer. |
323 TimeDelta total_time = Time::Now() - start_time; | 319 TimeDelta total_time = Time::Now() - start_time; |
324 EXPECT_GT(5000, total_time.InMilliseconds()); | 320 EXPECT_GT(5000, total_time.InMilliseconds()); |
325 | 321 |
326 // In case both timers somehow run at nearly the same time, sleep a little | 322 // In case both timers somehow run at nearly the same time, sleep a little |
327 // and then run all pending to force them both to have run. This is just | 323 // and then run all pending to force them both to have run. This is just |
328 // encouraging flakiness if there is any. | 324 // encouraging flakiness if there is any. |
329 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); | 325 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); |
330 base::RunLoop().RunUntilIdle(); | 326 RunLoop().RunUntilIdle(); |
331 | 327 |
332 EXPECT_TRUE(run_time1.is_null()); | 328 EXPECT_TRUE(run_time1.is_null()); |
333 EXPECT_FALSE(run_time2.is_null()); | 329 EXPECT_FALSE(run_time2.is_null()); |
334 } | 330 } |
335 | 331 |
336 #if defined(OS_WIN) | 332 #if defined(OS_WIN) |
337 | 333 |
338 void SubPumpFunc() { | 334 void SubPumpFunc() { |
339 MessageLoop::current()->SetNestableTasksAllowed(true); | 335 MessageLoop::current()->SetNestableTasksAllowed(true); |
340 MSG msg; | 336 MSG msg; |
341 while (GetMessage(&msg, NULL, 0, 0)) { | 337 while (GetMessage(&msg, NULL, 0, 0)) { |
342 TranslateMessage(&msg); | 338 TranslateMessage(&msg); |
343 DispatchMessage(&msg); | 339 DispatchMessage(&msg); |
344 } | 340 } |
345 MessageLoop::current()->QuitWhenIdle(); | 341 MessageLoop::current()->QuitWhenIdle(); |
346 } | 342 } |
347 | 343 |
348 void RunTest_PostDelayedTask_SharedTimer_SubPump() { | 344 void RunTest_PostDelayedTask_SharedTimer_SubPump() { |
349 MessageLoop loop(MessageLoop::TYPE_UI); | 345 MessageLoop loop(MessageLoop::TYPE_UI); |
350 | 346 |
351 // Test that the interval of the timer, used to run the next delayed task, is | 347 // Test that the interval of the timer, used to run the next delayed task, is |
352 // set to a value corresponding to when the next delayed task should run. | 348 // set to a value corresponding to when the next delayed task should run. |
353 | 349 |
354 // By setting num_tasks to 1, we ensure that the first task to run causes the | 350 // By setting num_tasks to 1, we ensure that the first task to run causes the |
355 // run loop to exit. | 351 // run loop to exit. |
356 int num_tasks = 1; | 352 int num_tasks = 1; |
357 Time run_time; | 353 Time run_time; |
358 | 354 |
359 loop.PostTask(FROM_HERE, base::Bind(&SubPumpFunc)); | 355 loop.PostTask(FROM_HERE, Bind(&SubPumpFunc)); |
360 | 356 |
361 // This very delayed task should never run. | 357 // This very delayed task should never run. |
362 loop.PostDelayedTask( | 358 loop.PostDelayedTask( |
363 FROM_HERE, | 359 FROM_HERE, |
364 base::Bind(&RecordRunTimeFunc, &run_time, &num_tasks), | 360 Bind(&RecordRunTimeFunc, &run_time, &num_tasks), |
365 TimeDelta::FromSeconds(1000)); | 361 TimeDelta::FromSeconds(1000)); |
366 | 362 |
367 // This slightly delayed task should run from within SubPumpFunc). | 363 // This slightly delayed task should run from within SubPumpFunc). |
368 loop.PostDelayedTask( | 364 loop.PostDelayedTask( |
369 FROM_HERE, | 365 FROM_HERE, |
370 base::Bind(&PostQuitMessage, 0), | 366 Bind(&PostQuitMessage, 0), |
371 TimeDelta::FromMilliseconds(10)); | 367 TimeDelta::FromMilliseconds(10)); |
372 | 368 |
373 Time start_time = Time::Now(); | 369 Time start_time = Time::Now(); |
374 | 370 |
375 loop.Run(); | 371 loop.Run(); |
376 EXPECT_EQ(1, num_tasks); | 372 EXPECT_EQ(1, num_tasks); |
377 | 373 |
378 // Ensure that we ran in far less time than the slower timer. | 374 // Ensure that we ran in far less time than the slower timer. |
379 TimeDelta total_time = Time::Now() - start_time; | 375 TimeDelta total_time = Time::Now() - start_time; |
380 EXPECT_GT(5000, total_time.InMilliseconds()); | 376 EXPECT_GT(5000, total_time.InMilliseconds()); |
381 | 377 |
382 // In case both timers somehow run at nearly the same time, sleep a little | 378 // In case both timers somehow run at nearly the same time, sleep a little |
383 // and then run all pending to force them both to have run. This is just | 379 // and then run all pending to force them both to have run. This is just |
384 // encouraging flakiness if there is any. | 380 // encouraging flakiness if there is any. |
385 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); | 381 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); |
386 base::RunLoop().RunUntilIdle(); | 382 RunLoop().RunUntilIdle(); |
387 | 383 |
388 EXPECT_TRUE(run_time.is_null()); | 384 EXPECT_TRUE(run_time.is_null()); |
389 } | 385 } |
390 | 386 |
391 #endif // defined(OS_WIN) | 387 #endif // defined(OS_WIN) |
392 | 388 |
393 // This is used to inject a test point for recording the destructor calls for | 389 // This is used to inject a test point for recording the destructor calls for |
394 // Closure objects send to MessageLoop::PostTask(). It is awkward usage since we | 390 // Closure objects send to MessageLoop::PostTask(). It is awkward usage since we |
395 // are trying to hook the actual destruction, which is not a common operation. | 391 // are trying to hook the actual destruction, which is not a common operation. |
396 class RecordDeletionProbe : public base::RefCounted<RecordDeletionProbe> { | 392 class RecordDeletionProbe : public RefCounted<RecordDeletionProbe> { |
397 public: | 393 public: |
398 RecordDeletionProbe(RecordDeletionProbe* post_on_delete, bool* was_deleted) | 394 RecordDeletionProbe(RecordDeletionProbe* post_on_delete, bool* was_deleted) |
399 : post_on_delete_(post_on_delete), was_deleted_(was_deleted) { | 395 : post_on_delete_(post_on_delete), was_deleted_(was_deleted) { |
400 } | 396 } |
401 void Run() {} | 397 void Run() {} |
402 | 398 |
403 private: | 399 private: |
404 friend class base::RefCounted<RecordDeletionProbe>; | 400 friend class RefCounted<RecordDeletionProbe>; |
405 | 401 |
406 ~RecordDeletionProbe() { | 402 ~RecordDeletionProbe() { |
407 *was_deleted_ = true; | 403 *was_deleted_ = true; |
408 if (post_on_delete_) | 404 if (post_on_delete_) |
409 MessageLoop::current()->PostTask( | 405 MessageLoop::current()->PostTask( |
410 FROM_HERE, | 406 FROM_HERE, |
411 base::Bind(&RecordDeletionProbe::Run, post_on_delete_.get())); | 407 Bind(&RecordDeletionProbe::Run, post_on_delete_.get())); |
412 } | 408 } |
413 | 409 |
414 scoped_refptr<RecordDeletionProbe> post_on_delete_; | 410 scoped_refptr<RecordDeletionProbe> post_on_delete_; |
415 bool* was_deleted_; | 411 bool* was_deleted_; |
416 }; | 412 }; |
417 | 413 |
418 void RunTest_EnsureDeletion(MessageLoop::Type message_loop_type) { | 414 void RunTest_EnsureDeletion(MessageLoop::Type message_loop_type) { |
419 bool a_was_deleted = false; | 415 bool a_was_deleted = false; |
420 bool b_was_deleted = false; | 416 bool b_was_deleted = false; |
421 { | 417 { |
422 MessageLoop loop(message_loop_type); | 418 MessageLoop loop(message_loop_type); |
423 loop.PostTask( | 419 loop.PostTask( |
424 FROM_HERE, base::Bind(&RecordDeletionProbe::Run, | 420 FROM_HERE, Bind(&RecordDeletionProbe::Run, |
425 new RecordDeletionProbe(NULL, &a_was_deleted))); | 421 new RecordDeletionProbe(NULL, &a_was_deleted))); |
426 // TODO(ajwong): Do we really need 1000ms here? | 422 // TODO(ajwong): Do we really need 1000ms here? |
427 loop.PostDelayedTask( | 423 loop.PostDelayedTask( |
428 FROM_HERE, base::Bind(&RecordDeletionProbe::Run, | 424 FROM_HERE, Bind(&RecordDeletionProbe::Run, |
429 new RecordDeletionProbe(NULL, &b_was_deleted)), | 425 new RecordDeletionProbe(NULL, &b_was_deleted)), |
430 TimeDelta::FromMilliseconds(1000)); | 426 TimeDelta::FromMilliseconds(1000)); |
431 } | 427 } |
432 EXPECT_TRUE(a_was_deleted); | 428 EXPECT_TRUE(a_was_deleted); |
433 EXPECT_TRUE(b_was_deleted); | 429 EXPECT_TRUE(b_was_deleted); |
434 } | 430 } |
435 | 431 |
436 void RunTest_EnsureDeletion_Chain(MessageLoop::Type message_loop_type) { | 432 void RunTest_EnsureDeletion_Chain(MessageLoop::Type message_loop_type) { |
437 bool a_was_deleted = false; | 433 bool a_was_deleted = false; |
438 bool b_was_deleted = false; | 434 bool b_was_deleted = false; |
439 bool c_was_deleted = false; | 435 bool c_was_deleted = false; |
440 { | 436 { |
441 MessageLoop loop(message_loop_type); | 437 MessageLoop loop(message_loop_type); |
442 // The scoped_refptr for each of the below is held either by the chained | 438 // The scoped_refptr for each of the below is held either by the chained |
443 // RecordDeletionProbe, or the bound RecordDeletionProbe::Run() callback. | 439 // RecordDeletionProbe, or the bound RecordDeletionProbe::Run() callback. |
444 RecordDeletionProbe* a = new RecordDeletionProbe(NULL, &a_was_deleted); | 440 RecordDeletionProbe* a = new RecordDeletionProbe(NULL, &a_was_deleted); |
445 RecordDeletionProbe* b = new RecordDeletionProbe(a, &b_was_deleted); | 441 RecordDeletionProbe* b = new RecordDeletionProbe(a, &b_was_deleted); |
446 RecordDeletionProbe* c = new RecordDeletionProbe(b, &c_was_deleted); | 442 RecordDeletionProbe* c = new RecordDeletionProbe(b, &c_was_deleted); |
447 loop.PostTask(FROM_HERE, base::Bind(&RecordDeletionProbe::Run, c)); | 443 loop.PostTask(FROM_HERE, Bind(&RecordDeletionProbe::Run, c)); |
448 } | 444 } |
449 EXPECT_TRUE(a_was_deleted); | 445 EXPECT_TRUE(a_was_deleted); |
450 EXPECT_TRUE(b_was_deleted); | 446 EXPECT_TRUE(b_was_deleted); |
451 EXPECT_TRUE(c_was_deleted); | 447 EXPECT_TRUE(c_was_deleted); |
452 } | 448 } |
453 | 449 |
454 void NestingFunc(int* depth) { | 450 void NestingFunc(int* depth) { |
455 if (*depth > 0) { | 451 if (*depth > 0) { |
456 *depth -= 1; | 452 *depth -= 1; |
457 MessageLoop::current()->PostTask(FROM_HERE, | 453 MessageLoop::current()->PostTask(FROM_HERE, |
458 base::Bind(&NestingFunc, depth)); | 454 Bind(&NestingFunc, depth)); |
459 | 455 |
460 MessageLoop::current()->SetNestableTasksAllowed(true); | 456 MessageLoop::current()->SetNestableTasksAllowed(true); |
461 MessageLoop::current()->Run(); | 457 MessageLoop::current()->Run(); |
462 } | 458 } |
463 MessageLoop::current()->QuitWhenIdle(); | 459 MessageLoop::current()->QuitWhenIdle(); |
464 } | 460 } |
465 | 461 |
466 #if defined(OS_WIN) | 462 #if defined(OS_WIN) |
467 | 463 |
468 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) { | 464 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) { |
469 ADD_FAILURE() << "bad exception handler"; | 465 ADD_FAILURE() << "bad exception handler"; |
470 ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode); | 466 ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode); |
471 return EXCEPTION_EXECUTE_HANDLER; | 467 return EXCEPTION_EXECUTE_HANDLER; |
472 } | 468 } |
473 | 469 |
474 // This task throws an SEH exception: initially write to an invalid address. | 470 // This task throws an SEH exception: initially write to an invalid address. |
475 // If the right SEH filter is installed, it will fix the error. | 471 // If the right SEH filter is installed, it will fix the error. |
476 class Crasher : public base::RefCounted<Crasher> { | 472 class Crasher : public RefCounted<Crasher> { |
477 public: | 473 public: |
478 // Ctor. If trash_SEH_handler is true, the task will override the unhandled | 474 // Ctor. If trash_SEH_handler is true, the task will override the unhandled |
479 // exception handler with one sure to crash this test. | 475 // exception handler with one sure to crash this test. |
480 explicit Crasher(bool trash_SEH_handler) | 476 explicit Crasher(bool trash_SEH_handler) |
481 : trash_SEH_handler_(trash_SEH_handler) { | 477 : trash_SEH_handler_(trash_SEH_handler) { |
482 } | 478 } |
483 | 479 |
484 void Run() { | 480 void Run() { |
485 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); | 481 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); |
486 if (trash_SEH_handler_) | 482 if (trash_SEH_handler_) |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 MessageLoop loop(message_loop_type); | 541 MessageLoop loop(message_loop_type); |
546 | 542 |
547 if (::IsDebuggerPresent()) | 543 if (::IsDebuggerPresent()) |
548 return; | 544 return; |
549 | 545 |
550 LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter = | 546 LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter = |
551 ::SetUnhandledExceptionFilter(&HandleCrasherException); | 547 ::SetUnhandledExceptionFilter(&HandleCrasherException); |
552 | 548 |
553 MessageLoop::current()->PostTask( | 549 MessageLoop::current()->PostTask( |
554 FROM_HERE, | 550 FROM_HERE, |
555 base::Bind(&Crasher::Run, new Crasher(false))); | 551 Bind(&Crasher::Run, new Crasher(false))); |
556 MessageLoop::current()->set_exception_restoration(true); | 552 MessageLoop::current()->set_exception_restoration(true); |
557 MessageLoop::current()->Run(); | 553 MessageLoop::current()->Run(); |
558 MessageLoop::current()->set_exception_restoration(false); | 554 MessageLoop::current()->set_exception_restoration(false); |
559 | 555 |
560 ::SetUnhandledExceptionFilter(old_SEH_filter); | 556 ::SetUnhandledExceptionFilter(old_SEH_filter); |
561 } | 557 } |
562 | 558 |
563 void RunTest_CrasherNasty(MessageLoop::Type message_loop_type) { | 559 void RunTest_CrasherNasty(MessageLoop::Type message_loop_type) { |
564 MessageLoop loop(message_loop_type); | 560 MessageLoop loop(message_loop_type); |
565 | 561 |
566 if (::IsDebuggerPresent()) | 562 if (::IsDebuggerPresent()) |
567 return; | 563 return; |
568 | 564 |
569 LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter = | 565 LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter = |
570 ::SetUnhandledExceptionFilter(&HandleCrasherException); | 566 ::SetUnhandledExceptionFilter(&HandleCrasherException); |
571 | 567 |
572 MessageLoop::current()->PostTask( | 568 MessageLoop::current()->PostTask( |
573 FROM_HERE, | 569 FROM_HERE, |
574 base::Bind(&Crasher::Run, new Crasher(true))); | 570 Bind(&Crasher::Run, new Crasher(true))); |
575 MessageLoop::current()->set_exception_restoration(true); | 571 MessageLoop::current()->set_exception_restoration(true); |
576 MessageLoop::current()->Run(); | 572 MessageLoop::current()->Run(); |
577 MessageLoop::current()->set_exception_restoration(false); | 573 MessageLoop::current()->set_exception_restoration(false); |
578 | 574 |
579 ::SetUnhandledExceptionFilter(old_SEH_filter); | 575 ::SetUnhandledExceptionFilter(old_SEH_filter); |
580 } | 576 } |
581 | 577 |
582 #endif // defined(OS_WIN) | 578 #endif // defined(OS_WIN) |
583 | 579 |
584 void RunTest_Nesting(MessageLoop::Type message_loop_type) { | 580 void RunTest_Nesting(MessageLoop::Type message_loop_type) { |
585 MessageLoop loop(message_loop_type); | 581 MessageLoop loop(message_loop_type); |
586 | 582 |
587 int depth = 100; | 583 int depth = 100; |
588 MessageLoop::current()->PostTask(FROM_HERE, | 584 MessageLoop::current()->PostTask(FROM_HERE, |
589 base::Bind(&NestingFunc, &depth)); | 585 Bind(&NestingFunc, &depth)); |
590 MessageLoop::current()->Run(); | 586 MessageLoop::current()->Run(); |
591 EXPECT_EQ(depth, 0); | 587 EXPECT_EQ(depth, 0); |
592 } | 588 } |
593 | 589 |
594 const wchar_t* const kMessageBoxTitle = L"MessageLoop Unit Test"; | 590 const wchar_t* const kMessageBoxTitle = L"MessageLoop Unit Test"; |
595 | 591 |
596 enum TaskType { | 592 enum TaskType { |
597 MESSAGEBOX, | 593 MESSAGEBOX, |
598 ENDDIALOG, | 594 ENDDIALOG, |
599 RECURSIVE, | 595 RECURSIVE, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 #endif // defined(OS_WIN) | 703 #endif // defined(OS_WIN) |
708 | 704 |
709 void RecursiveFunc(TaskList* order, int cookie, int depth, | 705 void RecursiveFunc(TaskList* order, int cookie, int depth, |
710 bool is_reentrant) { | 706 bool is_reentrant) { |
711 order->RecordStart(RECURSIVE, cookie); | 707 order->RecordStart(RECURSIVE, cookie); |
712 if (depth > 0) { | 708 if (depth > 0) { |
713 if (is_reentrant) | 709 if (is_reentrant) |
714 MessageLoop::current()->SetNestableTasksAllowed(true); | 710 MessageLoop::current()->SetNestableTasksAllowed(true); |
715 MessageLoop::current()->PostTask( | 711 MessageLoop::current()->PostTask( |
716 FROM_HERE, | 712 FROM_HERE, |
717 base::Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant)); | 713 Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant)); |
718 } | 714 } |
719 order->RecordEnd(RECURSIVE, cookie); | 715 order->RecordEnd(RECURSIVE, cookie); |
720 } | 716 } |
721 | 717 |
722 void RecursiveSlowFunc(TaskList* order, int cookie, int depth, | 718 void RecursiveSlowFunc(TaskList* order, int cookie, int depth, |
723 bool is_reentrant) { | 719 bool is_reentrant) { |
724 RecursiveFunc(order, cookie, depth, is_reentrant); | 720 RecursiveFunc(order, cookie, depth, is_reentrant); |
725 PlatformThread::Sleep(TimeDelta::FromMilliseconds(10)); | 721 PlatformThread::Sleep(TimeDelta::FromMilliseconds(10)); |
726 } | 722 } |
727 | 723 |
728 void QuitFunc(TaskList* order, int cookie) { | 724 void QuitFunc(TaskList* order, int cookie) { |
729 order->RecordStart(QUITMESSAGELOOP, cookie); | 725 order->RecordStart(QUITMESSAGELOOP, cookie); |
730 MessageLoop::current()->QuitWhenIdle(); | 726 MessageLoop::current()->QuitWhenIdle(); |
731 order->RecordEnd(QUITMESSAGELOOP, cookie); | 727 order->RecordEnd(QUITMESSAGELOOP, cookie); |
732 } | 728 } |
733 | 729 |
734 void SleepFunc(TaskList* order, int cookie, TimeDelta delay) { | 730 void SleepFunc(TaskList* order, int cookie, TimeDelta delay) { |
735 order->RecordStart(SLEEP, cookie); | 731 order->RecordStart(SLEEP, cookie); |
736 PlatformThread::Sleep(delay); | 732 PlatformThread::Sleep(delay); |
737 order->RecordEnd(SLEEP, cookie); | 733 order->RecordEnd(SLEEP, cookie); |
738 } | 734 } |
739 | 735 |
740 #if defined(OS_WIN) | 736 #if defined(OS_WIN) |
741 void RecursiveFuncWin(MessageLoop* target, | 737 void RecursiveFuncWin(MessageLoop* target, |
742 HANDLE event, | 738 HANDLE event, |
743 bool expect_window, | 739 bool expect_window, |
744 TaskList* order, | 740 TaskList* order, |
745 bool is_reentrant) { | 741 bool is_reentrant) { |
746 target->PostTask(FROM_HERE, | 742 target->PostTask(FROM_HERE, |
747 base::Bind(&RecursiveFunc, order, 1, 2, is_reentrant)); | 743 Bind(&RecursiveFunc, order, 1, 2, is_reentrant)); |
748 target->PostTask(FROM_HERE, | 744 target->PostTask(FROM_HERE, |
749 base::Bind(&MessageBoxFunc, order, 2, is_reentrant)); | 745 Bind(&MessageBoxFunc, order, 2, is_reentrant)); |
750 target->PostTask(FROM_HERE, | 746 target->PostTask(FROM_HERE, |
751 base::Bind(&RecursiveFunc, order, 3, 2, is_reentrant)); | 747 Bind(&RecursiveFunc, order, 3, 2, is_reentrant)); |
752 // The trick here is that for recursive task processing, this task will be | 748 // The trick here is that for recursive task processing, this task will be |
753 // ran _inside_ the MessageBox message loop, dismissing the MessageBox | 749 // ran _inside_ the MessageBox message loop, dismissing the MessageBox |
754 // without a chance. | 750 // without a chance. |
755 // For non-recursive task processing, this will be executed _after_ the | 751 // For non-recursive task processing, this will be executed _after_ the |
756 // MessageBox will have been dismissed by the code below, where | 752 // MessageBox will have been dismissed by the code below, where |
757 // expect_window_ is true. | 753 // expect_window_ is true. |
758 target->PostTask(FROM_HERE, | 754 target->PostTask(FROM_HERE, |
759 base::Bind(&EndDialogFunc, order, 4)); | 755 Bind(&EndDialogFunc, order, 4)); |
760 target->PostTask(FROM_HERE, | 756 target->PostTask(FROM_HERE, |
761 base::Bind(&QuitFunc, order, 5)); | 757 Bind(&QuitFunc, order, 5)); |
762 | 758 |
763 // Enforce that every tasks are sent before starting to run the main thread | 759 // Enforce that every tasks are sent before starting to run the main thread |
764 // message loop. | 760 // message loop. |
765 ASSERT_TRUE(SetEvent(event)); | 761 ASSERT_TRUE(SetEvent(event)); |
766 | 762 |
767 // Poll for the MessageBox. Don't do this at home! At the speed we do it, | 763 // Poll for the MessageBox. Don't do this at home! At the speed we do it, |
768 // you will never realize one MessageBox was shown. | 764 // you will never realize one MessageBox was shown. |
769 for (; expect_window;) { | 765 for (; expect_window;) { |
770 HWND window = FindWindow(L"#32770", kMessageBoxTitle); | 766 HWND window = FindWindow(L"#32770", kMessageBoxTitle); |
771 if (window) { | 767 if (window) { |
(...skipping 13 matching lines...) Expand all Loading... |
785 | 781 |
786 #endif // defined(OS_WIN) | 782 #endif // defined(OS_WIN) |
787 | 783 |
788 void RunTest_RecursiveDenial1(MessageLoop::Type message_loop_type) { | 784 void RunTest_RecursiveDenial1(MessageLoop::Type message_loop_type) { |
789 MessageLoop loop(message_loop_type); | 785 MessageLoop loop(message_loop_type); |
790 | 786 |
791 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); | 787 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); |
792 TaskList order; | 788 TaskList order; |
793 MessageLoop::current()->PostTask( | 789 MessageLoop::current()->PostTask( |
794 FROM_HERE, | 790 FROM_HERE, |
795 base::Bind(&RecursiveFunc, &order, 1, 2, false)); | 791 Bind(&RecursiveFunc, &order, 1, 2, false)); |
796 MessageLoop::current()->PostTask( | 792 MessageLoop::current()->PostTask( |
797 FROM_HERE, | 793 FROM_HERE, |
798 base::Bind(&RecursiveFunc, &order, 2, 2, false)); | 794 Bind(&RecursiveFunc, &order, 2, 2, false)); |
799 MessageLoop::current()->PostTask( | 795 MessageLoop::current()->PostTask( |
800 FROM_HERE, | 796 FROM_HERE, |
801 base::Bind(&QuitFunc, &order, 3)); | 797 Bind(&QuitFunc, &order, 3)); |
802 | 798 |
803 MessageLoop::current()->Run(); | 799 MessageLoop::current()->Run(); |
804 | 800 |
805 // FIFO order. | 801 // FIFO order. |
806 ASSERT_EQ(14U, order.Size()); | 802 ASSERT_EQ(14U, order.Size()); |
807 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | 803 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); |
808 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | 804 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); |
809 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | 805 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); |
810 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | 806 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); |
811 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | 807 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); |
812 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); | 808 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); |
813 EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true)); | 809 EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true)); |
814 EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false)); | 810 EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false)); |
815 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); | 811 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); |
816 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); | 812 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); |
817 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); | 813 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); |
818 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); | 814 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); |
819 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true)); | 815 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true)); |
820 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false)); | 816 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false)); |
821 } | 817 } |
822 | 818 |
823 void RunTest_RecursiveDenial3(MessageLoop::Type message_loop_type) { | 819 void RunTest_RecursiveDenial3(MessageLoop::Type message_loop_type) { |
824 MessageLoop loop(message_loop_type); | 820 MessageLoop loop(message_loop_type); |
825 | 821 |
826 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); | 822 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); |
827 TaskList order; | 823 TaskList order; |
828 MessageLoop::current()->PostTask( | 824 MessageLoop::current()->PostTask( |
829 FROM_HERE, base::Bind(&RecursiveSlowFunc, &order, 1, 2, false)); | 825 FROM_HERE, Bind(&RecursiveSlowFunc, &order, 1, 2, false)); |
830 MessageLoop::current()->PostTask( | 826 MessageLoop::current()->PostTask( |
831 FROM_HERE, base::Bind(&RecursiveSlowFunc, &order, 2, 2, false)); | 827 FROM_HERE, Bind(&RecursiveSlowFunc, &order, 2, 2, false)); |
832 MessageLoop::current()->PostDelayedTask( | 828 MessageLoop::current()->PostDelayedTask( |
833 FROM_HERE, | 829 FROM_HERE, |
834 base::Bind(&OrderedFunc, &order, 3), | 830 Bind(&OrderedFunc, &order, 3), |
835 TimeDelta::FromMilliseconds(5)); | 831 TimeDelta::FromMilliseconds(5)); |
836 MessageLoop::current()->PostDelayedTask( | 832 MessageLoop::current()->PostDelayedTask( |
837 FROM_HERE, | 833 FROM_HERE, |
838 base::Bind(&QuitFunc, &order, 4), | 834 Bind(&QuitFunc, &order, 4), |
839 TimeDelta::FromMilliseconds(5)); | 835 TimeDelta::FromMilliseconds(5)); |
840 | 836 |
841 MessageLoop::current()->Run(); | 837 MessageLoop::current()->Run(); |
842 | 838 |
843 // FIFO order. | 839 // FIFO order. |
844 ASSERT_EQ(16U, order.Size()); | 840 ASSERT_EQ(16U, order.Size()); |
845 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | 841 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); |
846 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | 842 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); |
847 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | 843 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); |
848 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | 844 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); |
849 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 1, true)); | 845 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 1, true)); |
850 EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 1, false)); | 846 EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 1, false)); |
851 EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 3, true)); | 847 EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 3, true)); |
852 EXPECT_EQ(order.Get(7), TaskItem(ORDERED, 3, false)); | 848 EXPECT_EQ(order.Get(7), TaskItem(ORDERED, 3, false)); |
853 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); | 849 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); |
854 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); | 850 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); |
855 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 4, true)); | 851 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 4, true)); |
856 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 4, false)); | 852 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 4, false)); |
857 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 1, true)); | 853 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 1, true)); |
858 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, false)); | 854 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, false)); |
859 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 2, true)); | 855 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 2, true)); |
860 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 2, false)); | 856 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 2, false)); |
861 } | 857 } |
862 | 858 |
863 void RunTest_RecursiveSupport1(MessageLoop::Type message_loop_type) { | 859 void RunTest_RecursiveSupport1(MessageLoop::Type message_loop_type) { |
864 MessageLoop loop(message_loop_type); | 860 MessageLoop loop(message_loop_type); |
865 | 861 |
866 TaskList order; | 862 TaskList order; |
867 MessageLoop::current()->PostTask( | 863 MessageLoop::current()->PostTask( |
868 FROM_HERE, base::Bind(&RecursiveFunc, &order, 1, 2, true)); | 864 FROM_HERE, Bind(&RecursiveFunc, &order, 1, 2, true)); |
869 MessageLoop::current()->PostTask( | 865 MessageLoop::current()->PostTask( |
870 FROM_HERE, base::Bind(&RecursiveFunc, &order, 2, 2, true)); | 866 FROM_HERE, Bind(&RecursiveFunc, &order, 2, 2, true)); |
871 MessageLoop::current()->PostTask( | 867 MessageLoop::current()->PostTask( |
872 FROM_HERE, base::Bind(&QuitFunc, &order, 3)); | 868 FROM_HERE, Bind(&QuitFunc, &order, 3)); |
873 | 869 |
874 MessageLoop::current()->Run(); | 870 MessageLoop::current()->Run(); |
875 | 871 |
876 // FIFO order. | 872 // FIFO order. |
877 ASSERT_EQ(14U, order.Size()); | 873 ASSERT_EQ(14U, order.Size()); |
878 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | 874 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); |
879 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | 875 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); |
880 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | 876 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); |
881 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | 877 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); |
882 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | 878 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); |
(...skipping 14 matching lines...) Expand all Loading... |
897 | 893 |
898 // A side effect of this test is the generation a beep. Sorry. | 894 // A side effect of this test is the generation a beep. Sorry. |
899 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { | 895 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { |
900 MessageLoop loop(message_loop_type); | 896 MessageLoop loop(message_loop_type); |
901 | 897 |
902 Thread worker("RecursiveDenial2_worker"); | 898 Thread worker("RecursiveDenial2_worker"); |
903 Thread::Options options; | 899 Thread::Options options; |
904 options.message_loop_type = message_loop_type; | 900 options.message_loop_type = message_loop_type; |
905 ASSERT_EQ(true, worker.StartWithOptions(options)); | 901 ASSERT_EQ(true, worker.StartWithOptions(options)); |
906 TaskList order; | 902 TaskList order; |
907 base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); | 903 win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); |
908 worker.message_loop()->PostTask(FROM_HERE, | 904 worker.message_loop()->PostTask(FROM_HERE, |
909 base::Bind(&RecursiveFuncWin, | 905 Bind(&RecursiveFuncWin, |
910 MessageLoop::current(), | 906 MessageLoop::current(), |
911 event.Get(), | 907 event.Get(), |
912 true, | 908 true, |
913 &order, | 909 &order, |
914 false)); | 910 false)); |
915 // Let the other thread execute. | 911 // Let the other thread execute. |
916 WaitForSingleObject(event, INFINITE); | 912 WaitForSingleObject(event, INFINITE); |
917 MessageLoop::current()->Run(); | 913 MessageLoop::current()->Run(); |
918 | 914 |
919 ASSERT_EQ(order.Size(), 17); | 915 ASSERT_EQ(order.Size(), 17); |
(...skipping 21 matching lines...) Expand all Loading... |
941 // A side effect of this test is the generation a beep. Sorry. This test also | 937 // A side effect of this test is the generation a beep. Sorry. This test also |
942 // needs to process windows messages on the current thread. | 938 // needs to process windows messages on the current thread. |
943 void RunTest_RecursiveSupport2(MessageLoop::Type message_loop_type) { | 939 void RunTest_RecursiveSupport2(MessageLoop::Type message_loop_type) { |
944 MessageLoop loop(message_loop_type); | 940 MessageLoop loop(message_loop_type); |
945 | 941 |
946 Thread worker("RecursiveSupport2_worker"); | 942 Thread worker("RecursiveSupport2_worker"); |
947 Thread::Options options; | 943 Thread::Options options; |
948 options.message_loop_type = message_loop_type; | 944 options.message_loop_type = message_loop_type; |
949 ASSERT_EQ(true, worker.StartWithOptions(options)); | 945 ASSERT_EQ(true, worker.StartWithOptions(options)); |
950 TaskList order; | 946 TaskList order; |
951 base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); | 947 win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); |
952 worker.message_loop()->PostTask(FROM_HERE, | 948 worker.message_loop()->PostTask(FROM_HERE, |
953 base::Bind(&RecursiveFuncWin, | 949 Bind(&RecursiveFuncWin, |
954 MessageLoop::current(), | 950 MessageLoop::current(), |
955 event.Get(), | 951 event.Get(), |
956 false, | 952 false, |
957 &order, | 953 &order, |
958 true)); | 954 true)); |
959 // Let the other thread execute. | 955 // Let the other thread execute. |
960 WaitForSingleObject(event, INFINITE); | 956 WaitForSingleObject(event, INFINITE); |
961 MessageLoop::current()->Run(); | 957 MessageLoop::current()->Run(); |
962 | 958 |
963 ASSERT_EQ(order.Size(), 18); | 959 ASSERT_EQ(order.Size(), 18); |
964 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | 960 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); |
965 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | 961 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); |
966 EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true)); | 962 EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true)); |
967 // Note that this executes in the MessageBox modal loop. | 963 // Note that this executes in the MessageBox modal loop. |
968 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 3, true)); | 964 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 3, true)); |
969 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, false)); | 965 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, false)); |
970 EXPECT_EQ(order.Get(5), TaskItem(ENDDIALOG, 4, true)); | 966 EXPECT_EQ(order.Get(5), TaskItem(ENDDIALOG, 4, true)); |
971 EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, false)); | 967 EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, false)); |
972 EXPECT_EQ(order.Get(7), TaskItem(MESSAGEBOX, 2, false)); | 968 EXPECT_EQ(order.Get(7), TaskItem(MESSAGEBOX, 2, false)); |
973 /* The order can subtly change here. The reason is that when RecursiveFunc(1) | 969 /* The order can subtly change here. The reason is that when RecursiveFunc(1) |
974 is called in the main thread, if it is faster than getting to the | 970 is called in the main thread, if it is faster than getting to the |
975 PostTask(FROM_HERE, base::Bind(&QuitFunc) execution, the order of task | 971 PostTask(FROM_HERE, Bind(&QuitFunc) execution, the order of task |
976 execution can change. We don't care anyway that the order isn't correct. | 972 execution can change. We don't care anyway that the order isn't correct. |
977 EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, true)); | 973 EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, true)); |
978 EXPECT_EQ(order.Get(9), TaskItem(QUITMESSAGELOOP, 5, false)); | 974 EXPECT_EQ(order.Get(9), TaskItem(QUITMESSAGELOOP, 5, false)); |
979 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); | 975 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); |
980 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); | 976 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); |
981 */ | 977 */ |
982 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true)); | 978 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true)); |
983 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false)); | 979 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false)); |
984 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true)); | 980 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true)); |
985 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false)); | 981 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false)); |
986 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true)); | 982 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true)); |
987 EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false)); | 983 EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false)); |
988 } | 984 } |
989 | 985 |
990 #endif // defined(OS_WIN) | 986 #endif // defined(OS_WIN) |
991 | 987 |
992 void FuncThatPumps(TaskList* order, int cookie) { | 988 void FuncThatPumps(TaskList* order, int cookie) { |
993 order->RecordStart(PUMPS, cookie); | 989 order->RecordStart(PUMPS, cookie); |
994 { | 990 { |
995 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); | 991 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); |
996 base::RunLoop().RunUntilIdle(); | 992 RunLoop().RunUntilIdle(); |
997 } | 993 } |
998 order->RecordEnd(PUMPS, cookie); | 994 order->RecordEnd(PUMPS, cookie); |
999 } | 995 } |
1000 | 996 |
1001 void FuncThatRuns(TaskList* order, int cookie, base::RunLoop* run_loop) { | 997 void FuncThatRuns(TaskList* order, int cookie, RunLoop* run_loop) { |
1002 order->RecordStart(RUNS, cookie); | 998 order->RecordStart(RUNS, cookie); |
1003 { | 999 { |
1004 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); | 1000 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); |
1005 run_loop->Run(); | 1001 run_loop->Run(); |
1006 } | 1002 } |
1007 order->RecordEnd(RUNS, cookie); | 1003 order->RecordEnd(RUNS, cookie); |
1008 } | 1004 } |
1009 | 1005 |
1010 void FuncThatQuitsNow() { | 1006 void FuncThatQuitsNow() { |
1011 MessageLoop::current()->QuitNow(); | 1007 MessageLoop::current()->QuitNow(); |
1012 } | 1008 } |
1013 | 1009 |
1014 // Tests that non nestable tasks run in FIFO if there are no nested loops. | 1010 // Tests that non nestable tasks run in FIFO if there are no nested loops. |
1015 void RunTest_NonNestableWithNoNesting( | 1011 void RunTest_NonNestableWithNoNesting( |
1016 MessageLoop::Type message_loop_type) { | 1012 MessageLoop::Type message_loop_type) { |
1017 MessageLoop loop(message_loop_type); | 1013 MessageLoop loop(message_loop_type); |
1018 | 1014 |
1019 TaskList order; | 1015 TaskList order; |
1020 | 1016 |
1021 MessageLoop::current()->PostNonNestableTask( | 1017 MessageLoop::current()->PostNonNestableTask( |
1022 FROM_HERE, | 1018 FROM_HERE, |
1023 base::Bind(&OrderedFunc, &order, 1)); | 1019 Bind(&OrderedFunc, &order, 1)); |
1024 MessageLoop::current()->PostTask(FROM_HERE, | 1020 MessageLoop::current()->PostTask(FROM_HERE, |
1025 base::Bind(&OrderedFunc, &order, 2)); | 1021 Bind(&OrderedFunc, &order, 2)); |
1026 MessageLoop::current()->PostTask(FROM_HERE, | 1022 MessageLoop::current()->PostTask(FROM_HERE, |
1027 base::Bind(&QuitFunc, &order, 3)); | 1023 Bind(&QuitFunc, &order, 3)); |
1028 MessageLoop::current()->Run(); | 1024 MessageLoop::current()->Run(); |
1029 | 1025 |
1030 // FIFO order. | 1026 // FIFO order. |
1031 ASSERT_EQ(6U, order.Size()); | 1027 ASSERT_EQ(6U, order.Size()); |
1032 EXPECT_EQ(order.Get(0), TaskItem(ORDERED, 1, true)); | 1028 EXPECT_EQ(order.Get(0), TaskItem(ORDERED, 1, true)); |
1033 EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 1, false)); | 1029 EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 1, false)); |
1034 EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 2, true)); | 1030 EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 2, true)); |
1035 EXPECT_EQ(order.Get(3), TaskItem(ORDERED, 2, false)); | 1031 EXPECT_EQ(order.Get(3), TaskItem(ORDERED, 2, false)); |
1036 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | 1032 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); |
1037 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); | 1033 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); |
1038 } | 1034 } |
1039 | 1035 |
1040 // Tests that non nestable tasks don't run when there's code in the call stack. | 1036 // Tests that non nestable tasks don't run when there's code in the call stack. |
1041 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type, | 1037 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type, |
1042 bool use_delayed) { | 1038 bool use_delayed) { |
1043 MessageLoop loop(message_loop_type); | 1039 MessageLoop loop(message_loop_type); |
1044 | 1040 |
1045 TaskList order; | 1041 TaskList order; |
1046 | 1042 |
1047 MessageLoop::current()->PostTask( | 1043 MessageLoop::current()->PostTask( |
1048 FROM_HERE, | 1044 FROM_HERE, |
1049 base::Bind(&FuncThatPumps, &order, 1)); | 1045 Bind(&FuncThatPumps, &order, 1)); |
1050 if (use_delayed) { | 1046 if (use_delayed) { |
1051 MessageLoop::current()->PostNonNestableDelayedTask( | 1047 MessageLoop::current()->PostNonNestableDelayedTask( |
1052 FROM_HERE, | 1048 FROM_HERE, |
1053 base::Bind(&OrderedFunc, &order, 2), | 1049 Bind(&OrderedFunc, &order, 2), |
1054 TimeDelta::FromMilliseconds(1)); | 1050 TimeDelta::FromMilliseconds(1)); |
1055 } else { | 1051 } else { |
1056 MessageLoop::current()->PostNonNestableTask( | 1052 MessageLoop::current()->PostNonNestableTask( |
1057 FROM_HERE, | 1053 FROM_HERE, |
1058 base::Bind(&OrderedFunc, &order, 2)); | 1054 Bind(&OrderedFunc, &order, 2)); |
1059 } | 1055 } |
1060 MessageLoop::current()->PostTask(FROM_HERE, | 1056 MessageLoop::current()->PostTask(FROM_HERE, |
1061 base::Bind(&OrderedFunc, &order, 3)); | 1057 Bind(&OrderedFunc, &order, 3)); |
1062 MessageLoop::current()->PostTask( | 1058 MessageLoop::current()->PostTask( |
1063 FROM_HERE, | 1059 FROM_HERE, |
1064 base::Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50))); | 1060 Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50))); |
1065 MessageLoop::current()->PostTask(FROM_HERE, | 1061 MessageLoop::current()->PostTask(FROM_HERE, |
1066 base::Bind(&OrderedFunc, &order, 5)); | 1062 Bind(&OrderedFunc, &order, 5)); |
1067 if (use_delayed) { | 1063 if (use_delayed) { |
1068 MessageLoop::current()->PostNonNestableDelayedTask( | 1064 MessageLoop::current()->PostNonNestableDelayedTask( |
1069 FROM_HERE, | 1065 FROM_HERE, |
1070 base::Bind(&QuitFunc, &order, 6), | 1066 Bind(&QuitFunc, &order, 6), |
1071 TimeDelta::FromMilliseconds(2)); | 1067 TimeDelta::FromMilliseconds(2)); |
1072 } else { | 1068 } else { |
1073 MessageLoop::current()->PostNonNestableTask( | 1069 MessageLoop::current()->PostNonNestableTask( |
1074 FROM_HERE, | 1070 FROM_HERE, |
1075 base::Bind(&QuitFunc, &order, 6)); | 1071 Bind(&QuitFunc, &order, 6)); |
1076 } | 1072 } |
1077 | 1073 |
1078 MessageLoop::current()->Run(); | 1074 MessageLoop::current()->Run(); |
1079 | 1075 |
1080 // FIFO order. | 1076 // FIFO order. |
1081 ASSERT_EQ(12U, order.Size()); | 1077 ASSERT_EQ(12U, order.Size()); |
1082 EXPECT_EQ(order.Get(0), TaskItem(PUMPS, 1, true)); | 1078 EXPECT_EQ(order.Get(0), TaskItem(PUMPS, 1, true)); |
1083 EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 3, true)); | 1079 EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 3, true)); |
1084 EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 3, false)); | 1080 EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 3, false)); |
1085 EXPECT_EQ(order.Get(3), TaskItem(SLEEP, 4, true)); | 1081 EXPECT_EQ(order.Get(3), TaskItem(SLEEP, 4, true)); |
1086 EXPECT_EQ(order.Get(4), TaskItem(SLEEP, 4, false)); | 1082 EXPECT_EQ(order.Get(4), TaskItem(SLEEP, 4, false)); |
1087 EXPECT_EQ(order.Get(5), TaskItem(ORDERED, 5, true)); | 1083 EXPECT_EQ(order.Get(5), TaskItem(ORDERED, 5, true)); |
1088 EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 5, false)); | 1084 EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 5, false)); |
1089 EXPECT_EQ(order.Get(7), TaskItem(PUMPS, 1, false)); | 1085 EXPECT_EQ(order.Get(7), TaskItem(PUMPS, 1, false)); |
1090 EXPECT_EQ(order.Get(8), TaskItem(ORDERED, 2, true)); | 1086 EXPECT_EQ(order.Get(8), TaskItem(ORDERED, 2, true)); |
1091 EXPECT_EQ(order.Get(9), TaskItem(ORDERED, 2, false)); | 1087 EXPECT_EQ(order.Get(9), TaskItem(ORDERED, 2, false)); |
1092 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 6, true)); | 1088 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 6, true)); |
1093 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 6, false)); | 1089 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 6, false)); |
1094 } | 1090 } |
1095 | 1091 |
1096 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | 1092 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. |
1097 void RunTest_QuitNow(MessageLoop::Type message_loop_type) { | 1093 void RunTest_QuitNow(MessageLoop::Type message_loop_type) { |
1098 MessageLoop loop(message_loop_type); | 1094 MessageLoop loop(message_loop_type); |
1099 | 1095 |
1100 TaskList order; | 1096 TaskList order; |
1101 | 1097 |
1102 base::RunLoop run_loop; | 1098 RunLoop run_loop; |
1103 | 1099 |
1104 MessageLoop::current()->PostTask(FROM_HERE, | 1100 MessageLoop::current()->PostTask(FROM_HERE, |
1105 base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&run_loop))); | 1101 Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop))); |
1106 MessageLoop::current()->PostTask( | 1102 MessageLoop::current()->PostTask( |
1107 FROM_HERE, base::Bind(&OrderedFunc, &order, 2)); | 1103 FROM_HERE, Bind(&OrderedFunc, &order, 2)); |
1108 MessageLoop::current()->PostTask( | 1104 MessageLoop::current()->PostTask( |
1109 FROM_HERE, base::Bind(&FuncThatQuitsNow)); | 1105 FROM_HERE, Bind(&FuncThatQuitsNow)); |
1110 MessageLoop::current()->PostTask( | 1106 MessageLoop::current()->PostTask( |
1111 FROM_HERE, base::Bind(&OrderedFunc, &order, 3)); | 1107 FROM_HERE, Bind(&OrderedFunc, &order, 3)); |
1112 MessageLoop::current()->PostTask( | 1108 MessageLoop::current()->PostTask( |
1113 FROM_HERE, base::Bind(&FuncThatQuitsNow)); | 1109 FROM_HERE, Bind(&FuncThatQuitsNow)); |
1114 MessageLoop::current()->PostTask( | 1110 MessageLoop::current()->PostTask( |
1115 FROM_HERE, base::Bind(&OrderedFunc, &order, 4)); // never runs | 1111 FROM_HERE, Bind(&OrderedFunc, &order, 4)); // never runs |
1116 | 1112 |
1117 MessageLoop::current()->Run(); | 1113 MessageLoop::current()->Run(); |
1118 | 1114 |
1119 ASSERT_EQ(6U, order.Size()); | 1115 ASSERT_EQ(6U, order.Size()); |
1120 int task_index = 0; | 1116 int task_index = 0; |
1121 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | 1117 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); |
1122 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | 1118 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); |
1123 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | 1119 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); |
1124 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | 1120 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); |
1125 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true)); | 1121 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true)); |
1126 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false)); | 1122 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false)); |
1127 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | 1123 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); |
1128 } | 1124 } |
1129 | 1125 |
1130 // Tests RunLoopQuit works before RunWithID. | 1126 // Tests RunLoopQuit works before RunWithID. |
1131 void RunTest_RunLoopQuitOrderBefore(MessageLoop::Type message_loop_type) { | 1127 void RunTest_RunLoopQuitOrderBefore(MessageLoop::Type message_loop_type) { |
1132 MessageLoop loop(message_loop_type); | 1128 MessageLoop loop(message_loop_type); |
1133 | 1129 |
1134 TaskList order; | 1130 TaskList order; |
1135 | 1131 |
1136 base::RunLoop run_loop; | 1132 RunLoop run_loop; |
1137 | 1133 |
1138 run_loop.Quit(); | 1134 run_loop.Quit(); |
1139 | 1135 |
1140 MessageLoop::current()->PostTask( | 1136 MessageLoop::current()->PostTask( |
1141 FROM_HERE, base::Bind(&OrderedFunc, &order, 1)); // never runs | 1137 FROM_HERE, Bind(&OrderedFunc, &order, 1)); // never runs |
1142 MessageLoop::current()->PostTask( | 1138 MessageLoop::current()->PostTask( |
1143 FROM_HERE, base::Bind(&FuncThatQuitsNow)); // never runs | 1139 FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs |
1144 | 1140 |
1145 run_loop.Run(); | 1141 run_loop.Run(); |
1146 | 1142 |
1147 ASSERT_EQ(0U, order.Size()); | 1143 ASSERT_EQ(0U, order.Size()); |
1148 } | 1144 } |
1149 | 1145 |
1150 // Tests RunLoopQuit works during RunWithID. | 1146 // Tests RunLoopQuit works during RunWithID. |
1151 void RunTest_RunLoopQuitOrderDuring(MessageLoop::Type message_loop_type) { | 1147 void RunTest_RunLoopQuitOrderDuring(MessageLoop::Type message_loop_type) { |
1152 MessageLoop loop(message_loop_type); | 1148 MessageLoop loop(message_loop_type); |
1153 | 1149 |
1154 TaskList order; | 1150 TaskList order; |
1155 | 1151 |
1156 base::RunLoop run_loop; | 1152 RunLoop run_loop; |
1157 | 1153 |
1158 MessageLoop::current()->PostTask( | 1154 MessageLoop::current()->PostTask( |
1159 FROM_HERE, base::Bind(&OrderedFunc, &order, 1)); | 1155 FROM_HERE, Bind(&OrderedFunc, &order, 1)); |
1160 MessageLoop::current()->PostTask( | 1156 MessageLoop::current()->PostTask( |
1161 FROM_HERE, run_loop.QuitClosure()); | 1157 FROM_HERE, run_loop.QuitClosure()); |
1162 MessageLoop::current()->PostTask( | 1158 MessageLoop::current()->PostTask( |
1163 FROM_HERE, base::Bind(&OrderedFunc, &order, 2)); // never runs | 1159 FROM_HERE, Bind(&OrderedFunc, &order, 2)); // never runs |
1164 MessageLoop::current()->PostTask( | 1160 MessageLoop::current()->PostTask( |
1165 FROM_HERE, base::Bind(&FuncThatQuitsNow)); // never runs | 1161 FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs |
1166 | 1162 |
1167 run_loop.Run(); | 1163 run_loop.Run(); |
1168 | 1164 |
1169 ASSERT_EQ(2U, order.Size()); | 1165 ASSERT_EQ(2U, order.Size()); |
1170 int task_index = 0; | 1166 int task_index = 0; |
1171 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, true)); | 1167 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, true)); |
1172 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, false)); | 1168 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, false)); |
1173 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | 1169 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); |
1174 } | 1170 } |
1175 | 1171 |
1176 // Tests RunLoopQuit works after RunWithID. | 1172 // Tests RunLoopQuit works after RunWithID. |
1177 void RunTest_RunLoopQuitOrderAfter(MessageLoop::Type message_loop_type) { | 1173 void RunTest_RunLoopQuitOrderAfter(MessageLoop::Type message_loop_type) { |
1178 MessageLoop loop(message_loop_type); | 1174 MessageLoop loop(message_loop_type); |
1179 | 1175 |
1180 TaskList order; | 1176 TaskList order; |
1181 | 1177 |
1182 base::RunLoop run_loop; | 1178 RunLoop run_loop; |
1183 | 1179 |
1184 MessageLoop::current()->PostTask(FROM_HERE, | 1180 MessageLoop::current()->PostTask(FROM_HERE, |
1185 base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&run_loop))); | 1181 Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop))); |
1186 MessageLoop::current()->PostTask( | 1182 MessageLoop::current()->PostTask( |
1187 FROM_HERE, base::Bind(&OrderedFunc, &order, 2)); | 1183 FROM_HERE, Bind(&OrderedFunc, &order, 2)); |
1188 MessageLoop::current()->PostTask( | 1184 MessageLoop::current()->PostTask( |
1189 FROM_HERE, base::Bind(&FuncThatQuitsNow)); | 1185 FROM_HERE, Bind(&FuncThatQuitsNow)); |
1190 MessageLoop::current()->PostTask( | 1186 MessageLoop::current()->PostTask( |
1191 FROM_HERE, base::Bind(&OrderedFunc, &order, 3)); | 1187 FROM_HERE, Bind(&OrderedFunc, &order, 3)); |
1192 MessageLoop::current()->PostTask( | 1188 MessageLoop::current()->PostTask( |
1193 FROM_HERE, run_loop.QuitClosure()); // has no affect | 1189 FROM_HERE, run_loop.QuitClosure()); // has no affect |
1194 MessageLoop::current()->PostTask( | 1190 MessageLoop::current()->PostTask( |
1195 FROM_HERE, base::Bind(&OrderedFunc, &order, 4)); | 1191 FROM_HERE, Bind(&OrderedFunc, &order, 4)); |
1196 MessageLoop::current()->PostTask( | 1192 MessageLoop::current()->PostTask( |
1197 FROM_HERE, base::Bind(&FuncThatQuitsNow)); | 1193 FROM_HERE, Bind(&FuncThatQuitsNow)); |
1198 | 1194 |
1199 base::RunLoop outer_run_loop; | 1195 RunLoop outer_run_loop; |
1200 outer_run_loop.Run(); | 1196 outer_run_loop.Run(); |
1201 | 1197 |
1202 ASSERT_EQ(8U, order.Size()); | 1198 ASSERT_EQ(8U, order.Size()); |
1203 int task_index = 0; | 1199 int task_index = 0; |
1204 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | 1200 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); |
1205 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | 1201 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); |
1206 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | 1202 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); |
1207 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | 1203 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); |
1208 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true)); | 1204 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true)); |
1209 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false)); | 1205 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false)); |
1210 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, true)); | 1206 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, true)); |
1211 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, false)); | 1207 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, false)); |
1212 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | 1208 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); |
1213 } | 1209 } |
1214 | 1210 |
1215 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | 1211 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. |
1216 void RunTest_RunLoopQuitTop(MessageLoop::Type message_loop_type) { | 1212 void RunTest_RunLoopQuitTop(MessageLoop::Type message_loop_type) { |
1217 MessageLoop loop(message_loop_type); | 1213 MessageLoop loop(message_loop_type); |
1218 | 1214 |
1219 TaskList order; | 1215 TaskList order; |
1220 | 1216 |
1221 base::RunLoop outer_run_loop; | 1217 RunLoop outer_run_loop; |
1222 base::RunLoop nested_run_loop; | 1218 RunLoop nested_run_loop; |
1223 | 1219 |
1224 MessageLoop::current()->PostTask(FROM_HERE, | 1220 MessageLoop::current()->PostTask(FROM_HERE, |
1225 base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&nested_run_loop))); | 1221 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); |
1226 MessageLoop::current()->PostTask( | 1222 MessageLoop::current()->PostTask( |
1227 FROM_HERE, outer_run_loop.QuitClosure()); | 1223 FROM_HERE, outer_run_loop.QuitClosure()); |
1228 MessageLoop::current()->PostTask( | 1224 MessageLoop::current()->PostTask( |
1229 FROM_HERE, base::Bind(&OrderedFunc, &order, 2)); | 1225 FROM_HERE, Bind(&OrderedFunc, &order, 2)); |
1230 MessageLoop::current()->PostTask( | 1226 MessageLoop::current()->PostTask( |
1231 FROM_HERE, nested_run_loop.QuitClosure()); | 1227 FROM_HERE, nested_run_loop.QuitClosure()); |
1232 | 1228 |
1233 outer_run_loop.Run(); | 1229 outer_run_loop.Run(); |
1234 | 1230 |
1235 ASSERT_EQ(4U, order.Size()); | 1231 ASSERT_EQ(4U, order.Size()); |
1236 int task_index = 0; | 1232 int task_index = 0; |
1237 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | 1233 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); |
1238 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | 1234 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); |
1239 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | 1235 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); |
1240 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | 1236 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); |
1241 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | 1237 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); |
1242 } | 1238 } |
1243 | 1239 |
1244 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | 1240 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. |
1245 void RunTest_RunLoopQuitNested(MessageLoop::Type message_loop_type) { | 1241 void RunTest_RunLoopQuitNested(MessageLoop::Type message_loop_type) { |
1246 MessageLoop loop(message_loop_type); | 1242 MessageLoop loop(message_loop_type); |
1247 | 1243 |
1248 TaskList order; | 1244 TaskList order; |
1249 | 1245 |
1250 base::RunLoop outer_run_loop; | 1246 RunLoop outer_run_loop; |
1251 base::RunLoop nested_run_loop; | 1247 RunLoop nested_run_loop; |
1252 | 1248 |
1253 MessageLoop::current()->PostTask(FROM_HERE, | 1249 MessageLoop::current()->PostTask(FROM_HERE, |
1254 base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&nested_run_loop))); | 1250 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); |
1255 MessageLoop::current()->PostTask( | 1251 MessageLoop::current()->PostTask( |
1256 FROM_HERE, nested_run_loop.QuitClosure()); | 1252 FROM_HERE, nested_run_loop.QuitClosure()); |
1257 MessageLoop::current()->PostTask( | 1253 MessageLoop::current()->PostTask( |
1258 FROM_HERE, base::Bind(&OrderedFunc, &order, 2)); | 1254 FROM_HERE, Bind(&OrderedFunc, &order, 2)); |
1259 MessageLoop::current()->PostTask( | 1255 MessageLoop::current()->PostTask( |
1260 FROM_HERE, outer_run_loop.QuitClosure()); | 1256 FROM_HERE, outer_run_loop.QuitClosure()); |
1261 | 1257 |
1262 outer_run_loop.Run(); | 1258 outer_run_loop.Run(); |
1263 | 1259 |
1264 ASSERT_EQ(4U, order.Size()); | 1260 ASSERT_EQ(4U, order.Size()); |
1265 int task_index = 0; | 1261 int task_index = 0; |
1266 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | 1262 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); |
1267 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | 1263 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); |
1268 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | 1264 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); |
1269 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | 1265 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); |
1270 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | 1266 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); |
1271 } | 1267 } |
1272 | 1268 |
1273 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | 1269 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. |
1274 void RunTest_RunLoopQuitBogus(MessageLoop::Type message_loop_type) { | 1270 void RunTest_RunLoopQuitBogus(MessageLoop::Type message_loop_type) { |
1275 MessageLoop loop(message_loop_type); | 1271 MessageLoop loop(message_loop_type); |
1276 | 1272 |
1277 TaskList order; | 1273 TaskList order; |
1278 | 1274 |
1279 base::RunLoop outer_run_loop; | 1275 RunLoop outer_run_loop; |
1280 base::RunLoop nested_run_loop; | 1276 RunLoop nested_run_loop; |
1281 base::RunLoop bogus_run_loop; | 1277 RunLoop bogus_run_loop; |
1282 | 1278 |
1283 MessageLoop::current()->PostTask(FROM_HERE, | 1279 MessageLoop::current()->PostTask(FROM_HERE, |
1284 base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&nested_run_loop))); | 1280 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); |
1285 MessageLoop::current()->PostTask( | 1281 MessageLoop::current()->PostTask( |
1286 FROM_HERE, bogus_run_loop.QuitClosure()); | 1282 FROM_HERE, bogus_run_loop.QuitClosure()); |
1287 MessageLoop::current()->PostTask( | 1283 MessageLoop::current()->PostTask( |
1288 FROM_HERE, base::Bind(&OrderedFunc, &order, 2)); | 1284 FROM_HERE, Bind(&OrderedFunc, &order, 2)); |
1289 MessageLoop::current()->PostTask( | 1285 MessageLoop::current()->PostTask( |
1290 FROM_HERE, outer_run_loop.QuitClosure()); | 1286 FROM_HERE, outer_run_loop.QuitClosure()); |
1291 MessageLoop::current()->PostTask( | 1287 MessageLoop::current()->PostTask( |
1292 FROM_HERE, nested_run_loop.QuitClosure()); | 1288 FROM_HERE, nested_run_loop.QuitClosure()); |
1293 | 1289 |
1294 outer_run_loop.Run(); | 1290 outer_run_loop.Run(); |
1295 | 1291 |
1296 ASSERT_EQ(4U, order.Size()); | 1292 ASSERT_EQ(4U, order.Size()); |
1297 int task_index = 0; | 1293 int task_index = 0; |
1298 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | 1294 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); |
1299 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | 1295 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); |
1300 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | 1296 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); |
1301 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | 1297 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); |
1302 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | 1298 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); |
1303 } | 1299 } |
1304 | 1300 |
1305 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | 1301 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. |
1306 void RunTest_RunLoopQuitDeep(MessageLoop::Type message_loop_type) { | 1302 void RunTest_RunLoopQuitDeep(MessageLoop::Type message_loop_type) { |
1307 MessageLoop loop(message_loop_type); | 1303 MessageLoop loop(message_loop_type); |
1308 | 1304 |
1309 TaskList order; | 1305 TaskList order; |
1310 | 1306 |
1311 base::RunLoop outer_run_loop; | 1307 RunLoop outer_run_loop; |
1312 base::RunLoop nested_loop1; | 1308 RunLoop nested_loop1; |
1313 base::RunLoop nested_loop2; | 1309 RunLoop nested_loop2; |
1314 base::RunLoop nested_loop3; | 1310 RunLoop nested_loop3; |
1315 base::RunLoop nested_loop4; | 1311 RunLoop nested_loop4; |
1316 | 1312 |
1317 MessageLoop::current()->PostTask(FROM_HERE, | 1313 MessageLoop::current()->PostTask(FROM_HERE, |
1318 base::Bind(&FuncThatRuns, &order, 1, base::Unretained(&nested_loop1))); | 1314 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_loop1))); |
1319 MessageLoop::current()->PostTask(FROM_HERE, | 1315 MessageLoop::current()->PostTask(FROM_HERE, |
1320 base::Bind(&FuncThatRuns, &order, 2, base::Unretained(&nested_loop2))); | 1316 Bind(&FuncThatRuns, &order, 2, Unretained(&nested_loop2))); |
1321 MessageLoop::current()->PostTask(FROM_HERE, | 1317 MessageLoop::current()->PostTask(FROM_HERE, |
1322 base::Bind(&FuncThatRuns, &order, 3, base::Unretained(&nested_loop3))); | 1318 Bind(&FuncThatRuns, &order, 3, Unretained(&nested_loop3))); |
1323 MessageLoop::current()->PostTask(FROM_HERE, | 1319 MessageLoop::current()->PostTask(FROM_HERE, |
1324 base::Bind(&FuncThatRuns, &order, 4, base::Unretained(&nested_loop4))); | 1320 Bind(&FuncThatRuns, &order, 4, Unretained(&nested_loop4))); |
1325 MessageLoop::current()->PostTask( | 1321 MessageLoop::current()->PostTask( |
1326 FROM_HERE, base::Bind(&OrderedFunc, &order, 5)); | 1322 FROM_HERE, Bind(&OrderedFunc, &order, 5)); |
1327 MessageLoop::current()->PostTask( | 1323 MessageLoop::current()->PostTask( |
1328 FROM_HERE, outer_run_loop.QuitClosure()); | 1324 FROM_HERE, outer_run_loop.QuitClosure()); |
1329 MessageLoop::current()->PostTask( | 1325 MessageLoop::current()->PostTask( |
1330 FROM_HERE, base::Bind(&OrderedFunc, &order, 6)); | 1326 FROM_HERE, Bind(&OrderedFunc, &order, 6)); |
1331 MessageLoop::current()->PostTask( | 1327 MessageLoop::current()->PostTask( |
1332 FROM_HERE, nested_loop1.QuitClosure()); | 1328 FROM_HERE, nested_loop1.QuitClosure()); |
1333 MessageLoop::current()->PostTask( | 1329 MessageLoop::current()->PostTask( |
1334 FROM_HERE, base::Bind(&OrderedFunc, &order, 7)); | 1330 FROM_HERE, Bind(&OrderedFunc, &order, 7)); |
1335 MessageLoop::current()->PostTask( | 1331 MessageLoop::current()->PostTask( |
1336 FROM_HERE, nested_loop2.QuitClosure()); | 1332 FROM_HERE, nested_loop2.QuitClosure()); |
1337 MessageLoop::current()->PostTask( | 1333 MessageLoop::current()->PostTask( |
1338 FROM_HERE, base::Bind(&OrderedFunc, &order, 8)); | 1334 FROM_HERE, Bind(&OrderedFunc, &order, 8)); |
1339 MessageLoop::current()->PostTask( | 1335 MessageLoop::current()->PostTask( |
1340 FROM_HERE, nested_loop3.QuitClosure()); | 1336 FROM_HERE, nested_loop3.QuitClosure()); |
1341 MessageLoop::current()->PostTask( | 1337 MessageLoop::current()->PostTask( |
1342 FROM_HERE, base::Bind(&OrderedFunc, &order, 9)); | 1338 FROM_HERE, Bind(&OrderedFunc, &order, 9)); |
1343 MessageLoop::current()->PostTask( | 1339 MessageLoop::current()->PostTask( |
1344 FROM_HERE, nested_loop4.QuitClosure()); | 1340 FROM_HERE, nested_loop4.QuitClosure()); |
1345 MessageLoop::current()->PostTask( | 1341 MessageLoop::current()->PostTask( |
1346 FROM_HERE, base::Bind(&OrderedFunc, &order, 10)); | 1342 FROM_HERE, Bind(&OrderedFunc, &order, 10)); |
1347 | 1343 |
1348 outer_run_loop.Run(); | 1344 outer_run_loop.Run(); |
1349 | 1345 |
1350 ASSERT_EQ(18U, order.Size()); | 1346 ASSERT_EQ(18U, order.Size()); |
1351 int task_index = 0; | 1347 int task_index = 0; |
1352 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | 1348 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); |
1353 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, true)); | 1349 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, true)); |
1354 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, true)); | 1350 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, true)); |
1355 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, true)); | 1351 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, true)); |
1356 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, true)); | 1352 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, true)); |
(...skipping 10 matching lines...) Expand all Loading... |
1367 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, false)); | 1363 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, false)); |
1368 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, false)); | 1364 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, false)); |
1369 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | 1365 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); |
1370 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | 1366 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); |
1371 } | 1367 } |
1372 | 1368 |
1373 void PostNTasksThenQuit(int posts_remaining) { | 1369 void PostNTasksThenQuit(int posts_remaining) { |
1374 if (posts_remaining > 1) { | 1370 if (posts_remaining > 1) { |
1375 MessageLoop::current()->PostTask( | 1371 MessageLoop::current()->PostTask( |
1376 FROM_HERE, | 1372 FROM_HERE, |
1377 base::Bind(&PostNTasksThenQuit, posts_remaining - 1)); | 1373 Bind(&PostNTasksThenQuit, posts_remaining - 1)); |
1378 } else { | 1374 } else { |
1379 MessageLoop::current()->QuitWhenIdle(); | 1375 MessageLoop::current()->QuitWhenIdle(); |
1380 } | 1376 } |
1381 } | 1377 } |
1382 | 1378 |
1383 void RunTest_RecursivePosts(MessageLoop::Type message_loop_type, | 1379 void RunTest_RecursivePosts(MessageLoop::Type message_loop_type, |
1384 int num_times) { | 1380 int num_times) { |
1385 MessageLoop loop(message_loop_type); | 1381 MessageLoop loop(message_loop_type); |
1386 loop.PostTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, num_times)); | 1382 loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, num_times)); |
1387 loop.Run(); | 1383 loop.Run(); |
1388 } | 1384 } |
1389 | 1385 |
1390 #if defined(OS_WIN) | 1386 #if defined(OS_WIN) |
1391 | 1387 |
1392 class DispatcherImpl : public MessageLoopForUI::Dispatcher { | 1388 class DispatcherImpl : public MessageLoopForUI::Dispatcher { |
1393 public: | 1389 public: |
1394 DispatcherImpl() : dispatch_count_(0) {} | 1390 DispatcherImpl() : dispatch_count_(0) {} |
1395 | 1391 |
1396 virtual bool Dispatch(const base::NativeEvent& msg) OVERRIDE { | 1392 virtual bool Dispatch(const NativeEvent& msg) OVERRIDE { |
1397 ::TranslateMessage(&msg); | 1393 ::TranslateMessage(&msg); |
1398 ::DispatchMessage(&msg); | 1394 ::DispatchMessage(&msg); |
1399 // Do not count WM_TIMER since it is not what we post and it will cause | 1395 // Do not count WM_TIMER since it is not what we post and it will cause |
1400 // flakiness. | 1396 // flakiness. |
1401 if (msg.message != WM_TIMER) | 1397 if (msg.message != WM_TIMER) |
1402 ++dispatch_count_; | 1398 ++dispatch_count_; |
1403 // We treat WM_LBUTTONUP as the last message. | 1399 // We treat WM_LBUTTONUP as the last message. |
1404 return msg.message != WM_LBUTTONUP; | 1400 return msg.message != WM_LBUTTONUP; |
1405 } | 1401 } |
1406 | 1402 |
1407 int dispatch_count_; | 1403 int dispatch_count_; |
1408 }; | 1404 }; |
1409 | 1405 |
1410 void MouseDownUp() { | 1406 void MouseDownUp() { |
1411 PostMessage(NULL, WM_LBUTTONDOWN, 0, 0); | 1407 PostMessage(NULL, WM_LBUTTONDOWN, 0, 0); |
1412 PostMessage(NULL, WM_LBUTTONUP, 'A', 0); | 1408 PostMessage(NULL, WM_LBUTTONUP, 'A', 0); |
1413 } | 1409 } |
1414 | 1410 |
1415 void RunTest_Dispatcher(MessageLoop::Type message_loop_type) { | 1411 void RunTest_Dispatcher(MessageLoop::Type message_loop_type) { |
1416 MessageLoop loop(message_loop_type); | 1412 MessageLoop loop(message_loop_type); |
1417 | 1413 |
1418 MessageLoop::current()->PostDelayedTask( | 1414 MessageLoop::current()->PostDelayedTask( |
1419 FROM_HERE, | 1415 FROM_HERE, |
1420 base::Bind(&MouseDownUp), | 1416 Bind(&MouseDownUp), |
1421 TimeDelta::FromMilliseconds(100)); | 1417 TimeDelta::FromMilliseconds(100)); |
1422 DispatcherImpl dispatcher; | 1418 DispatcherImpl dispatcher; |
1423 base::RunLoop run_loop(&dispatcher); | 1419 RunLoop run_loop(&dispatcher); |
1424 run_loop.Run(); | 1420 run_loop.Run(); |
1425 ASSERT_EQ(2, dispatcher.dispatch_count_); | 1421 ASSERT_EQ(2, dispatcher.dispatch_count_); |
1426 } | 1422 } |
1427 | 1423 |
1428 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) { | 1424 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) { |
1429 if (code == base::MessagePumpForUI::kMessageFilterCode) { | 1425 if (code == MessagePumpForUI::kMessageFilterCode) { |
1430 MSG* msg = reinterpret_cast<MSG*>(lparam); | 1426 MSG* msg = reinterpret_cast<MSG*>(lparam); |
1431 if (msg->message == WM_LBUTTONDOWN) | 1427 if (msg->message == WM_LBUTTONDOWN) |
1432 return TRUE; | 1428 return TRUE; |
1433 } | 1429 } |
1434 return FALSE; | 1430 return FALSE; |
1435 } | 1431 } |
1436 | 1432 |
1437 void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) { | 1433 void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) { |
1438 MessageLoop loop(message_loop_type); | 1434 MessageLoop loop(message_loop_type); |
1439 | 1435 |
1440 MessageLoop::current()->PostDelayedTask( | 1436 MessageLoop::current()->PostDelayedTask( |
1441 FROM_HERE, | 1437 FROM_HERE, |
1442 base::Bind(&MouseDownUp), | 1438 Bind(&MouseDownUp), |
1443 TimeDelta::FromMilliseconds(100)); | 1439 TimeDelta::FromMilliseconds(100)); |
1444 HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER, | 1440 HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER, |
1445 MsgFilterProc, | 1441 MsgFilterProc, |
1446 NULL, | 1442 NULL, |
1447 GetCurrentThreadId()); | 1443 GetCurrentThreadId()); |
1448 DispatcherImpl dispatcher; | 1444 DispatcherImpl dispatcher; |
1449 base::RunLoop run_loop(&dispatcher); | 1445 RunLoop run_loop(&dispatcher); |
1450 run_loop.Run(); | 1446 run_loop.Run(); |
1451 ASSERT_EQ(1, dispatcher.dispatch_count_); | 1447 ASSERT_EQ(1, dispatcher.dispatch_count_); |
1452 UnhookWindowsHookEx(msg_hook); | 1448 UnhookWindowsHookEx(msg_hook); |
1453 } | 1449 } |
1454 | 1450 |
1455 class TestIOHandler : public MessageLoopForIO::IOHandler { | 1451 class TestIOHandler : public MessageLoopForIO::IOHandler { |
1456 public: | 1452 public: |
1457 TestIOHandler(const wchar_t* name, HANDLE signal, bool wait); | 1453 TestIOHandler(const wchar_t* name, HANDLE signal, bool wait); |
1458 | 1454 |
1459 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, | 1455 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
1460 DWORD bytes_transfered, DWORD error); | 1456 DWORD bytes_transfered, DWORD error); |
1461 | 1457 |
1462 void Init(); | 1458 void Init(); |
1463 void WaitForIO(); | 1459 void WaitForIO(); |
1464 OVERLAPPED* context() { return &context_.overlapped; } | 1460 OVERLAPPED* context() { return &context_.overlapped; } |
1465 DWORD size() { return sizeof(buffer_); } | 1461 DWORD size() { return sizeof(buffer_); } |
1466 | 1462 |
1467 private: | 1463 private: |
1468 char buffer_[48]; | 1464 char buffer_[48]; |
1469 MessageLoopForIO::IOContext context_; | 1465 MessageLoopForIO::IOContext context_; |
1470 HANDLE signal_; | 1466 HANDLE signal_; |
1471 base::win::ScopedHandle file_; | 1467 win::ScopedHandle file_; |
1472 bool wait_; | 1468 bool wait_; |
1473 }; | 1469 }; |
1474 | 1470 |
1475 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait) | 1471 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait) |
1476 : signal_(signal), wait_(wait) { | 1472 : signal_(signal), wait_(wait) { |
1477 memset(buffer_, 0, sizeof(buffer_)); | 1473 memset(buffer_, 0, sizeof(buffer_)); |
1478 memset(&context_, 0, sizeof(context_)); | 1474 memset(&context_, 0, sizeof(context_)); |
1479 context_.handler = this; | 1475 context_.handler = this; |
1480 | 1476 |
1481 file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, | 1477 file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, |
(...skipping 16 matching lines...) Expand all Loading... |
1498 ASSERT_TRUE(context == &context_); | 1494 ASSERT_TRUE(context == &context_); |
1499 ASSERT_TRUE(SetEvent(signal_)); | 1495 ASSERT_TRUE(SetEvent(signal_)); |
1500 } | 1496 } |
1501 | 1497 |
1502 void TestIOHandler::WaitForIO() { | 1498 void TestIOHandler::WaitForIO() { |
1503 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this)); | 1499 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this)); |
1504 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this)); | 1500 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this)); |
1505 } | 1501 } |
1506 | 1502 |
1507 void RunTest_IOHandler() { | 1503 void RunTest_IOHandler() { |
1508 base::win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL)); | 1504 win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL)); |
1509 ASSERT_TRUE(callback_called.IsValid()); | 1505 ASSERT_TRUE(callback_called.IsValid()); |
1510 | 1506 |
1511 const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe"; | 1507 const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe"; |
1512 base::win::ScopedHandle server( | 1508 win::ScopedHandle server( |
1513 CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); | 1509 CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); |
1514 ASSERT_TRUE(server.IsValid()); | 1510 ASSERT_TRUE(server.IsValid()); |
1515 | 1511 |
1516 Thread thread("IOHandler test"); | 1512 Thread thread("IOHandler test"); |
1517 Thread::Options options; | 1513 Thread::Options options; |
1518 options.message_loop_type = MessageLoop::TYPE_IO; | 1514 options.message_loop_type = MessageLoop::TYPE_IO; |
1519 ASSERT_TRUE(thread.StartWithOptions(options)); | 1515 ASSERT_TRUE(thread.StartWithOptions(options)); |
1520 | 1516 |
1521 MessageLoop* thread_loop = thread.message_loop(); | 1517 MessageLoop* thread_loop = thread.message_loop(); |
1522 ASSERT_TRUE(NULL != thread_loop); | 1518 ASSERT_TRUE(NULL != thread_loop); |
1523 | 1519 |
1524 TestIOHandler handler(kPipeName, callback_called, false); | 1520 TestIOHandler handler(kPipeName, callback_called, false); |
1525 thread_loop->PostTask(FROM_HERE, base::Bind(&TestIOHandler::Init, | 1521 thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init, |
1526 base::Unretained(&handler))); | 1522 Unretained(&handler))); |
1527 // Make sure the thread runs and sleeps for lack of work. | 1523 // Make sure the thread runs and sleeps for lack of work. |
1528 base::PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); | 1524 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); |
1529 | 1525 |
1530 const char buffer[] = "Hello there!"; | 1526 const char buffer[] = "Hello there!"; |
1531 DWORD written; | 1527 DWORD written; |
1532 EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL)); | 1528 EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL)); |
1533 | 1529 |
1534 DWORD result = WaitForSingleObject(callback_called, 1000); | 1530 DWORD result = WaitForSingleObject(callback_called, 1000); |
1535 EXPECT_EQ(WAIT_OBJECT_0, result); | 1531 EXPECT_EQ(WAIT_OBJECT_0, result); |
1536 | 1532 |
1537 thread.Stop(); | 1533 thread.Stop(); |
1538 } | 1534 } |
1539 | 1535 |
1540 void RunTest_WaitForIO() { | 1536 void RunTest_WaitForIO() { |
1541 base::win::ScopedHandle callback1_called( | 1537 win::ScopedHandle callback1_called( |
1542 CreateEvent(NULL, TRUE, FALSE, NULL)); | 1538 CreateEvent(NULL, TRUE, FALSE, NULL)); |
1543 base::win::ScopedHandle callback2_called( | 1539 win::ScopedHandle callback2_called( |
1544 CreateEvent(NULL, TRUE, FALSE, NULL)); | 1540 CreateEvent(NULL, TRUE, FALSE, NULL)); |
1545 ASSERT_TRUE(callback1_called.IsValid()); | 1541 ASSERT_TRUE(callback1_called.IsValid()); |
1546 ASSERT_TRUE(callback2_called.IsValid()); | 1542 ASSERT_TRUE(callback2_called.IsValid()); |
1547 | 1543 |
1548 const wchar_t* kPipeName1 = L"\\\\.\\pipe\\iohandler_pipe1"; | 1544 const wchar_t* kPipeName1 = L"\\\\.\\pipe\\iohandler_pipe1"; |
1549 const wchar_t* kPipeName2 = L"\\\\.\\pipe\\iohandler_pipe2"; | 1545 const wchar_t* kPipeName2 = L"\\\\.\\pipe\\iohandler_pipe2"; |
1550 base::win::ScopedHandle server1( | 1546 win::ScopedHandle server1( |
1551 CreateNamedPipe(kPipeName1, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); | 1547 CreateNamedPipe(kPipeName1, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); |
1552 base::win::ScopedHandle server2( | 1548 win::ScopedHandle server2( |
1553 CreateNamedPipe(kPipeName2, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); | 1549 CreateNamedPipe(kPipeName2, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); |
1554 ASSERT_TRUE(server1.IsValid()); | 1550 ASSERT_TRUE(server1.IsValid()); |
1555 ASSERT_TRUE(server2.IsValid()); | 1551 ASSERT_TRUE(server2.IsValid()); |
1556 | 1552 |
1557 Thread thread("IOHandler test"); | 1553 Thread thread("IOHandler test"); |
1558 Thread::Options options; | 1554 Thread::Options options; |
1559 options.message_loop_type = MessageLoop::TYPE_IO; | 1555 options.message_loop_type = MessageLoop::TYPE_IO; |
1560 ASSERT_TRUE(thread.StartWithOptions(options)); | 1556 ASSERT_TRUE(thread.StartWithOptions(options)); |
1561 | 1557 |
1562 MessageLoop* thread_loop = thread.message_loop(); | 1558 MessageLoop* thread_loop = thread.message_loop(); |
1563 ASSERT_TRUE(NULL != thread_loop); | 1559 ASSERT_TRUE(NULL != thread_loop); |
1564 | 1560 |
1565 TestIOHandler handler1(kPipeName1, callback1_called, false); | 1561 TestIOHandler handler1(kPipeName1, callback1_called, false); |
1566 TestIOHandler handler2(kPipeName2, callback2_called, true); | 1562 TestIOHandler handler2(kPipeName2, callback2_called, true); |
1567 thread_loop->PostTask(FROM_HERE, base::Bind(&TestIOHandler::Init, | 1563 thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init, |
1568 base::Unretained(&handler1))); | 1564 Unretained(&handler1))); |
1569 // TODO(ajwong): Do we really need such long Sleeps in ths function? | 1565 // TODO(ajwong): Do we really need such long Sleeps in ths function? |
1570 // Make sure the thread runs and sleeps for lack of work. | 1566 // Make sure the thread runs and sleeps for lack of work. |
1571 TimeDelta delay = TimeDelta::FromMilliseconds(100); | 1567 TimeDelta delay = TimeDelta::FromMilliseconds(100); |
1572 base::PlatformThread::Sleep(delay); | 1568 PlatformThread::Sleep(delay); |
1573 thread_loop->PostTask(FROM_HERE, base::Bind(&TestIOHandler::Init, | 1569 thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init, |
1574 base::Unretained(&handler2))); | 1570 Unretained(&handler2))); |
1575 base::PlatformThread::Sleep(delay); | 1571 PlatformThread::Sleep(delay); |
1576 | 1572 |
1577 // At this time handler1 is waiting to be called, and the thread is waiting | 1573 // At this time handler1 is waiting to be called, and the thread is waiting |
1578 // on the Init method of handler2, filtering only handler2 callbacks. | 1574 // on the Init method of handler2, filtering only handler2 callbacks. |
1579 | 1575 |
1580 const char buffer[] = "Hello there!"; | 1576 const char buffer[] = "Hello there!"; |
1581 DWORD written; | 1577 DWORD written; |
1582 EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL)); | 1578 EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL)); |
1583 base::PlatformThread::Sleep(2 * delay); | 1579 PlatformThread::Sleep(2 * delay); |
1584 EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) << | 1580 EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) << |
1585 "handler1 has not been called"; | 1581 "handler1 has not been called"; |
1586 | 1582 |
1587 EXPECT_TRUE(WriteFile(server2, buffer, sizeof(buffer), &written, NULL)); | 1583 EXPECT_TRUE(WriteFile(server2, buffer, sizeof(buffer), &written, NULL)); |
1588 | 1584 |
1589 HANDLE objects[2] = { callback1_called.Get(), callback2_called.Get() }; | 1585 HANDLE objects[2] = { callback1_called.Get(), callback2_called.Get() }; |
1590 DWORD result = WaitForMultipleObjects(2, objects, TRUE, 1000); | 1586 DWORD result = WaitForMultipleObjects(2, objects, TRUE, 1000); |
1591 EXPECT_EQ(WAIT_OBJECT_0, result); | 1587 EXPECT_EQ(WAIT_OBJECT_0, result); |
1592 | 1588 |
1593 thread.Stop(); | 1589 thread.Stop(); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1794 | 1790 |
1795 class DummyTaskObserver : public MessageLoop::TaskObserver { | 1791 class DummyTaskObserver : public MessageLoop::TaskObserver { |
1796 public: | 1792 public: |
1797 explicit DummyTaskObserver(int num_tasks) | 1793 explicit DummyTaskObserver(int num_tasks) |
1798 : num_tasks_started_(0), | 1794 : num_tasks_started_(0), |
1799 num_tasks_processed_(0), | 1795 num_tasks_processed_(0), |
1800 num_tasks_(num_tasks) {} | 1796 num_tasks_(num_tasks) {} |
1801 | 1797 |
1802 virtual ~DummyTaskObserver() {} | 1798 virtual ~DummyTaskObserver() {} |
1803 | 1799 |
1804 virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE { | 1800 virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE { |
1805 num_tasks_started_++; | 1801 num_tasks_started_++; |
1806 EXPECT_TRUE(pending_task.time_posted != TimeTicks()); | 1802 EXPECT_TRUE(pending_task.time_posted != TimeTicks()); |
1807 EXPECT_LE(num_tasks_started_, num_tasks_); | 1803 EXPECT_LE(num_tasks_started_, num_tasks_); |
1808 EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1); | 1804 EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1); |
1809 } | 1805 } |
1810 | 1806 |
1811 virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE { | 1807 virtual void DidProcessTask(const PendingTask& pending_task) OVERRIDE { |
1812 num_tasks_processed_++; | 1808 num_tasks_processed_++; |
1813 EXPECT_TRUE(pending_task.time_posted != TimeTicks()); | 1809 EXPECT_TRUE(pending_task.time_posted != TimeTicks()); |
1814 EXPECT_LE(num_tasks_started_, num_tasks_); | 1810 EXPECT_LE(num_tasks_started_, num_tasks_); |
1815 EXPECT_EQ(num_tasks_started_, num_tasks_processed_); | 1811 EXPECT_EQ(num_tasks_started_, num_tasks_processed_); |
1816 } | 1812 } |
1817 | 1813 |
1818 int num_tasks_started() const { return num_tasks_started_; } | 1814 int num_tasks_started() const { return num_tasks_started_; } |
1819 int num_tasks_processed() const { return num_tasks_processed_; } | 1815 int num_tasks_processed() const { return num_tasks_processed_; } |
1820 | 1816 |
1821 private: | 1817 private: |
1822 int num_tasks_started_; | 1818 int num_tasks_started_; |
1823 int num_tasks_processed_; | 1819 int num_tasks_processed_; |
1824 const int num_tasks_; | 1820 const int num_tasks_; |
1825 | 1821 |
1826 DISALLOW_COPY_AND_ASSIGN(DummyTaskObserver); | 1822 DISALLOW_COPY_AND_ASSIGN(DummyTaskObserver); |
1827 }; | 1823 }; |
1828 | 1824 |
1829 TEST(MessageLoopTest, TaskObserver) { | 1825 TEST(MessageLoopTest, TaskObserver) { |
1830 const int kNumPosts = 6; | 1826 const int kNumPosts = 6; |
1831 DummyTaskObserver observer(kNumPosts); | 1827 DummyTaskObserver observer(kNumPosts); |
1832 | 1828 |
1833 MessageLoop loop; | 1829 MessageLoop loop; |
1834 loop.AddTaskObserver(&observer); | 1830 loop.AddTaskObserver(&observer); |
1835 loop.PostTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, kNumPosts)); | 1831 loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, kNumPosts)); |
1836 loop.Run(); | 1832 loop.Run(); |
1837 loop.RemoveTaskObserver(&observer); | 1833 loop.RemoveTaskObserver(&observer); |
1838 | 1834 |
1839 EXPECT_EQ(kNumPosts, observer.num_tasks_started()); | 1835 EXPECT_EQ(kNumPosts, observer.num_tasks_started()); |
1840 EXPECT_EQ(kNumPosts, observer.num_tasks_processed()); | 1836 EXPECT_EQ(kNumPosts, observer.num_tasks_processed()); |
1841 } | 1837 } |
1842 | 1838 |
1843 #if defined(OS_WIN) | 1839 #if defined(OS_WIN) |
1844 TEST(MessageLoopTest, Dispatcher) { | 1840 TEST(MessageLoopTest, Dispatcher) { |
1845 // This test requires a UI loop | 1841 // This test requires a UI loop |
(...skipping 15 matching lines...) Expand all Loading... |
1861 | 1857 |
1862 TEST(MessageLoopTest, HighResolutionTimer) { | 1858 TEST(MessageLoopTest, HighResolutionTimer) { |
1863 MessageLoop loop; | 1859 MessageLoop loop; |
1864 | 1860 |
1865 const TimeDelta kFastTimer = TimeDelta::FromMilliseconds(5); | 1861 const TimeDelta kFastTimer = TimeDelta::FromMilliseconds(5); |
1866 const TimeDelta kSlowTimer = TimeDelta::FromMilliseconds(100); | 1862 const TimeDelta kSlowTimer = TimeDelta::FromMilliseconds(100); |
1867 | 1863 |
1868 EXPECT_FALSE(loop.high_resolution_timers_enabled()); | 1864 EXPECT_FALSE(loop.high_resolution_timers_enabled()); |
1869 | 1865 |
1870 // Post a fast task to enable the high resolution timers. | 1866 // Post a fast task to enable the high resolution timers. |
1871 loop.PostDelayedTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, 1), | 1867 loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1), |
1872 kFastTimer); | 1868 kFastTimer); |
1873 loop.Run(); | 1869 loop.Run(); |
1874 EXPECT_TRUE(loop.high_resolution_timers_enabled()); | 1870 EXPECT_TRUE(loop.high_resolution_timers_enabled()); |
1875 | 1871 |
1876 // Post a slow task and verify high resolution timers | 1872 // Post a slow task and verify high resolution timers |
1877 // are still enabled. | 1873 // are still enabled. |
1878 loop.PostDelayedTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, 1), | 1874 loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1), |
1879 kSlowTimer); | 1875 kSlowTimer); |
1880 loop.Run(); | 1876 loop.Run(); |
1881 EXPECT_TRUE(loop.high_resolution_timers_enabled()); | 1877 EXPECT_TRUE(loop.high_resolution_timers_enabled()); |
1882 | 1878 |
1883 // Wait for a while so that high-resolution mode elapses. | 1879 // Wait for a while so that high-resolution mode elapses. |
1884 base::PlatformThread::Sleep(TimeDelta::FromMilliseconds( | 1880 PlatformThread::Sleep(TimeDelta::FromMilliseconds( |
1885 MessageLoop::kHighResolutionTimerModeLeaseTimeMs)); | 1881 MessageLoop::kHighResolutionTimerModeLeaseTimeMs)); |
1886 | 1882 |
1887 // Post a slow task to disable the high resolution timers. | 1883 // Post a slow task to disable the high resolution timers. |
1888 loop.PostDelayedTask(FROM_HERE, base::Bind(&PostNTasksThenQuit, 1), | 1884 loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1), |
1889 kSlowTimer); | 1885 kSlowTimer); |
1890 loop.Run(); | 1886 loop.Run(); |
1891 EXPECT_FALSE(loop.high_resolution_timers_enabled()); | 1887 EXPECT_FALSE(loop.high_resolution_timers_enabled()); |
1892 } | 1888 } |
1893 | 1889 |
1894 #endif // defined(OS_WIN) | 1890 #endif // defined(OS_WIN) |
1895 | 1891 |
1896 #if defined(OS_POSIX) && !defined(OS_NACL) | 1892 #if defined(OS_POSIX) && !defined(OS_NACL) |
1897 | 1893 |
1898 namespace { | 1894 namespace { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 | 1959 |
1964 } // namespace | 1960 } // namespace |
1965 | 1961 |
1966 #endif // defined(OS_POSIX) && !defined(OS_NACL) | 1962 #endif // defined(OS_POSIX) && !defined(OS_NACL) |
1967 | 1963 |
1968 namespace { | 1964 namespace { |
1969 // Inject a test point for recording the destructor calls for Closure objects | 1965 // Inject a test point for recording the destructor calls for Closure objects |
1970 // send to MessageLoop::PostTask(). It is awkward usage since we are trying to | 1966 // send to MessageLoop::PostTask(). It is awkward usage since we are trying to |
1971 // hook the actual destruction, which is not a common operation. | 1967 // hook the actual destruction, which is not a common operation. |
1972 class DestructionObserverProbe : | 1968 class DestructionObserverProbe : |
1973 public base::RefCounted<DestructionObserverProbe> { | 1969 public RefCounted<DestructionObserverProbe> { |
1974 public: | 1970 public: |
1975 DestructionObserverProbe(bool* task_destroyed, | 1971 DestructionObserverProbe(bool* task_destroyed, |
1976 bool* destruction_observer_called) | 1972 bool* destruction_observer_called) |
1977 : task_destroyed_(task_destroyed), | 1973 : task_destroyed_(task_destroyed), |
1978 destruction_observer_called_(destruction_observer_called) { | 1974 destruction_observer_called_(destruction_observer_called) { |
1979 } | 1975 } |
1980 virtual void Run() { | 1976 virtual void Run() { |
1981 // This task should never run. | 1977 // This task should never run. |
1982 ADD_FAILURE(); | 1978 ADD_FAILURE(); |
1983 } | 1979 } |
1984 private: | 1980 private: |
1985 friend class base::RefCounted<DestructionObserverProbe>; | 1981 friend class RefCounted<DestructionObserverProbe>; |
1986 | 1982 |
1987 virtual ~DestructionObserverProbe() { | 1983 virtual ~DestructionObserverProbe() { |
1988 EXPECT_FALSE(*destruction_observer_called_); | 1984 EXPECT_FALSE(*destruction_observer_called_); |
1989 *task_destroyed_ = true; | 1985 *task_destroyed_ = true; |
1990 } | 1986 } |
1991 | 1987 |
1992 bool* task_destroyed_; | 1988 bool* task_destroyed_; |
1993 bool* destruction_observer_called_; | 1989 bool* destruction_observer_called_; |
1994 }; | 1990 }; |
1995 | 1991 |
(...skipping 25 matching lines...) Expand all Loading... |
2021 MessageLoop* loop = new MessageLoop; | 2017 MessageLoop* loop = new MessageLoop; |
2022 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); | 2018 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); |
2023 | 2019 |
2024 bool task_destroyed = false; | 2020 bool task_destroyed = false; |
2025 bool destruction_observer_called = false; | 2021 bool destruction_observer_called = false; |
2026 | 2022 |
2027 MLDestructionObserver observer(&task_destroyed, &destruction_observer_called); | 2023 MLDestructionObserver observer(&task_destroyed, &destruction_observer_called); |
2028 loop->AddDestructionObserver(&observer); | 2024 loop->AddDestructionObserver(&observer); |
2029 loop->PostDelayedTask( | 2025 loop->PostDelayedTask( |
2030 FROM_HERE, | 2026 FROM_HERE, |
2031 base::Bind(&DestructionObserverProbe::Run, | 2027 Bind(&DestructionObserverProbe::Run, |
2032 new DestructionObserverProbe(&task_destroyed, | 2028 new DestructionObserverProbe(&task_destroyed, |
2033 &destruction_observer_called)), | 2029 &destruction_observer_called)), |
2034 kDelay); | 2030 kDelay); |
2035 delete loop; | 2031 delete loop; |
2036 EXPECT_TRUE(observer.task_destroyed_before_message_loop()); | 2032 EXPECT_TRUE(observer.task_destroyed_before_message_loop()); |
2037 // The task should have been destroyed when we deleted the loop. | 2033 // The task should have been destroyed when we deleted the loop. |
2038 EXPECT_TRUE(task_destroyed); | 2034 EXPECT_TRUE(task_destroyed); |
2039 EXPECT_TRUE(destruction_observer_called); | 2035 EXPECT_TRUE(destruction_observer_called); |
2040 } | 2036 } |
2041 | 2037 |
2042 | 2038 |
2043 // Verify that MessageLoop sets ThreadMainTaskRunner::current() and it | 2039 // Verify that MessageLoop sets ThreadMainTaskRunner::current() and it |
2044 // posts tasks on that message loop. | 2040 // posts tasks on that message loop. |
2045 TEST(MessageLoopTest, ThreadMainTaskRunner) { | 2041 TEST(MessageLoopTest, ThreadMainTaskRunner) { |
2046 MessageLoop loop; | 2042 MessageLoop loop; |
2047 | 2043 |
2048 scoped_refptr<Foo> foo(new Foo()); | 2044 scoped_refptr<Foo> foo(new Foo()); |
2049 std::string a("a"); | 2045 std::string a("a"); |
2050 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind( | 2046 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, Bind( |
2051 &Foo::Test1ConstRef, foo.get(), a)); | 2047 &Foo::Test1ConstRef, foo.get(), a)); |
2052 | 2048 |
2053 // Post quit task; | 2049 // Post quit task; |
2054 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 2050 MessageLoop::current()->PostTask(FROM_HERE, Bind( |
2055 &MessageLoop::Quit, base::Unretained(MessageLoop::current()))); | 2051 &MessageLoop::Quit, Unretained(MessageLoop::current()))); |
2056 | 2052 |
2057 // Now kick things off | 2053 // Now kick things off |
2058 MessageLoop::current()->Run(); | 2054 MessageLoop::current()->Run(); |
2059 | 2055 |
2060 EXPECT_EQ(foo->test_count(), 1); | 2056 EXPECT_EQ(foo->test_count(), 1); |
2061 EXPECT_EQ(foo->result(), "a"); | 2057 EXPECT_EQ(foo->result(), "a"); |
2062 } | 2058 } |
2063 | 2059 |
2064 TEST(MessageLoopTest, IsType) { | 2060 TEST(MessageLoopTest, IsType) { |
2065 MessageLoop loop(MessageLoop::TYPE_UI); | 2061 MessageLoop loop(MessageLoop::TYPE_UI); |
2066 EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); | 2062 EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); |
2067 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); | 2063 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); |
2068 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); | 2064 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); |
2069 } | 2065 } |
2070 | 2066 |
2071 TEST(MessageLoopTest, RecursivePosts) { | 2067 TEST(MessageLoopTest, RecursivePosts) { |
2072 // There was a bug in the MessagePumpGLib where posting tasks recursively | 2068 // There was a bug in the MessagePumpGLib where posting tasks recursively |
2073 // caused the message loop to hang, due to the buffer of the internal pipe | 2069 // caused the message loop to hang, due to the buffer of the internal pipe |
2074 // becoming full. Test all MessageLoop types to ensure this issue does not | 2070 // becoming full. Test all MessageLoop types to ensure this issue does not |
2075 // exist in other MessagePumps. | 2071 // exist in other MessagePumps. |
2076 | 2072 |
2077 // On Linux, the pipe buffer size is 64KiB by default. The bug caused one | 2073 // On Linux, the pipe buffer size is 64KiB by default. The bug caused one |
2078 // byte accumulated in the pipe per two posts, so we should repeat 128K | 2074 // byte accumulated in the pipe per two posts, so we should repeat 128K |
2079 // times to reproduce the bug. | 2075 // times to reproduce the bug. |
2080 const int kNumTimes = 1 << 17; | 2076 const int kNumTimes = 1 << 17; |
2081 RunTest_RecursivePosts(MessageLoop::TYPE_DEFAULT, kNumTimes); | 2077 RunTest_RecursivePosts(MessageLoop::TYPE_DEFAULT, kNumTimes); |
2082 RunTest_RecursivePosts(MessageLoop::TYPE_UI, kNumTimes); | 2078 RunTest_RecursivePosts(MessageLoop::TYPE_UI, kNumTimes); |
2083 RunTest_RecursivePosts(MessageLoop::TYPE_IO, kNumTimes); | 2079 RunTest_RecursivePosts(MessageLoop::TYPE_IO, kNumTimes); |
2084 } | 2080 } |
| 2081 |
| 2082 } // namespace base |
OLD | NEW |