OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/message_loop/message_loop_proxy_impl.h" | 13 #include "base/message_loop/message_loop_proxy_impl.h" |
| 14 #include "base/message_loop/message_loop_test.h" |
14 #include "base/pending_task.h" | 15 #include "base/pending_task.h" |
15 #include "base/posix/eintr_wrapper.h" | 16 #include "base/posix/eintr_wrapper.h" |
16 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
17 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
18 #include "base/thread_task_runner_handle.h" | 19 #include "base/thread_task_runner_handle.h" |
19 #include "base/threading/platform_thread.h" | 20 #include "base/threading/platform_thread.h" |
20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
22 | 23 |
23 #if defined(OS_WIN) | 24 #if defined(OS_WIN) |
24 #include "base/message_loop/message_pump_win.h" | 25 #include "base/message_loop/message_pump_win.h" |
25 #include "base/win/scoped_handle.h" | 26 #include "base/win/scoped_handle.h" |
26 #endif | 27 #endif |
27 | 28 |
28 namespace base { | 29 namespace base { |
29 | 30 |
30 // TODO(darin): Platform-specific MessageLoop tests should be grouped together | 31 // TODO(darin): Platform-specific MessageLoop tests should be grouped together |
31 // to avoid chopping this file up with so many #ifdefs. | 32 // to avoid chopping this file up with so many #ifdefs. |
32 | 33 |
33 namespace { | 34 namespace { |
34 | 35 |
| 36 MessagePump* TypeDefaultMessagePumpFactory() { |
| 37 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_DEFAULT); |
| 38 } |
| 39 |
| 40 MessagePump* TypeIOMessagePumpFactory() { |
| 41 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_IO); |
| 42 } |
| 43 |
| 44 MessagePump* TypeUIMessagePumpFactory() { |
| 45 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_UI); |
| 46 } |
| 47 |
35 class Foo : public RefCounted<Foo> { | 48 class Foo : public RefCounted<Foo> { |
36 public: | 49 public: |
37 Foo() : test_count_(0) { | 50 Foo() : test_count_(0) { |
38 } | 51 } |
39 | 52 |
40 void Test0() { | 53 void Test0() { |
41 ++test_count_; | 54 ++test_count_; |
42 } | 55 } |
43 | 56 |
44 void Test1ConstRef(const std::string& a) { | 57 void Test1ConstRef(const std::string& a) { |
(...skipping 27 matching lines...) Expand all Loading... |
72 | 85 |
73 private: | 86 private: |
74 friend class RefCounted<Foo>; | 87 friend class RefCounted<Foo>; |
75 | 88 |
76 ~Foo() {} | 89 ~Foo() {} |
77 | 90 |
78 int test_count_; | 91 int test_count_; |
79 std::string result_; | 92 std::string result_; |
80 }; | 93 }; |
81 | 94 |
82 void RunTest_PostTask(MessageLoop::Type message_loop_type) { | 95 #if defined(OS_WIN) |
83 MessageLoop loop(message_loop_type); | |
84 | |
85 // Add tests to message loop | |
86 scoped_refptr<Foo> foo(new Foo()); | |
87 std::string a("a"), b("b"), c("c"), d("d"); | |
88 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
89 &Foo::Test0, foo.get())); | |
90 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
91 &Foo::Test1ConstRef, foo.get(), a)); | |
92 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
93 &Foo::Test1Ptr, foo.get(), &b)); | |
94 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
95 &Foo::Test1Int, foo.get(), 100)); | |
96 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
97 &Foo::Test2Ptr, foo.get(), &a, &c)); | |
98 | |
99 // TryPost with no contention. It must succeed. | |
100 EXPECT_TRUE(MessageLoop::current()->TryPostTask(FROM_HERE, Bind( | |
101 &Foo::Test2Mixed, foo.get(), a, &d))); | |
102 | |
103 // TryPost with simulated contention. It must fail. We wait for a helper | |
104 // thread to lock the queue, we TryPost on this thread and finally we | |
105 // signal the helper to unlock and exit. | |
106 WaitableEvent wait(true, false); | |
107 WaitableEvent signal(true, false); | |
108 Thread thread("RunTest_PostTask_helper"); | |
109 thread.Start(); | |
110 thread.message_loop()->PostTask( | |
111 FROM_HERE, | |
112 Bind(&MessageLoop::LockWaitUnLockForTesting, | |
113 base::Unretained(MessageLoop::current()), | |
114 &wait, | |
115 &signal)); | |
116 | |
117 wait.Wait(); | |
118 EXPECT_FALSE(MessageLoop::current()->TryPostTask(FROM_HERE, Bind( | |
119 &Foo::Test2Mixed, foo.get(), a, &d))); | |
120 signal.Signal(); | |
121 | |
122 // After all tests, post a message that will shut down the message loop | |
123 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
124 &MessageLoop::Quit, Unretained(MessageLoop::current()))); | |
125 | |
126 // Now kick things off | |
127 MessageLoop::current()->Run(); | |
128 | |
129 EXPECT_EQ(foo->test_count(), 105); | |
130 EXPECT_EQ(foo->result(), "abacad"); | |
131 } | |
132 | |
133 void RunTest_PostTask_SEH(MessageLoop::Type message_loop_type) { | |
134 MessageLoop loop(message_loop_type); | |
135 | |
136 // Add tests to message loop | |
137 scoped_refptr<Foo> foo(new Foo()); | |
138 std::string a("a"), b("b"), c("c"), d("d"); | |
139 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
140 &Foo::Test0, foo.get())); | |
141 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
142 &Foo::Test1ConstRef, foo.get(), a)); | |
143 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
144 &Foo::Test1Ptr, foo.get(), &b)); | |
145 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
146 &Foo::Test1Int, foo.get(), 100)); | |
147 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
148 &Foo::Test2Ptr, foo.get(), &a, &c)); | |
149 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
150 &Foo::Test2Mixed, foo.get(), a, &d)); | |
151 | |
152 // After all tests, post a message that will shut down the message loop | |
153 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
154 &MessageLoop::Quit, Unretained(MessageLoop::current()))); | |
155 | |
156 // Now kick things off with the SEH block active. | |
157 MessageLoop::current()->set_exception_restoration(true); | |
158 MessageLoop::current()->Run(); | |
159 MessageLoop::current()->set_exception_restoration(false); | |
160 | |
161 EXPECT_EQ(foo->test_count(), 105); | |
162 EXPECT_EQ(foo->result(), "abacad"); | |
163 } | |
164 | 96 |
165 // This function runs slowly to simulate a large amount of work being done. | 97 // This function runs slowly to simulate a large amount of work being done. |
166 static void SlowFunc(TimeDelta pause, int* quit_counter) { | 98 static void SlowFunc(TimeDelta pause, int* quit_counter) { |
167 PlatformThread::Sleep(pause); | 99 PlatformThread::Sleep(pause); |
168 if (--(*quit_counter) == 0) | 100 if (--(*quit_counter) == 0) |
169 MessageLoop::current()->QuitWhenIdle(); | 101 MessageLoop::current()->QuitWhenIdle(); |
170 } | 102 } |
171 | 103 |
172 // This function records the time when Run was called in a Time object, which is | 104 // This function records the time when Run was called in a Time object, which is |
173 // useful for building a variety of MessageLoop tests. | 105 // useful for building a variety of MessageLoop tests. |
174 static void RecordRunTimeFunc(Time* run_time, int* quit_counter) { | 106 static void RecordRunTimeFunc(Time* run_time, int* quit_counter) { |
175 *run_time = Time::Now(); | 107 *run_time = Time::Now(); |
176 | 108 |
177 // Cause our Run function to take some time to execute. As a result we can | 109 // Cause our Run function to take some time to execute. As a result we can |
178 // count on subsequent RecordRunTimeFunc()s running at a future time, | 110 // count on subsequent RecordRunTimeFunc()s running at a future time, |
179 // without worry about the resolution of our system clock being an issue. | 111 // without worry about the resolution of our system clock being an issue. |
180 SlowFunc(TimeDelta::FromMilliseconds(10), quit_counter); | 112 SlowFunc(TimeDelta::FromMilliseconds(10), quit_counter); |
181 } | 113 } |
182 | 114 |
183 void RunTest_PostDelayedTask_Basic(MessageLoop::Type message_loop_type) { | |
184 MessageLoop loop(message_loop_type); | |
185 | |
186 // Test that PostDelayedTask results in a delayed task. | |
187 | |
188 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); | |
189 | |
190 int num_tasks = 1; | |
191 Time run_time; | |
192 | |
193 loop.PostDelayedTask( | |
194 FROM_HERE, Bind(&RecordRunTimeFunc, &run_time, &num_tasks), | |
195 kDelay); | |
196 | |
197 Time time_before_run = Time::Now(); | |
198 loop.Run(); | |
199 Time time_after_run = Time::Now(); | |
200 | |
201 EXPECT_EQ(0, num_tasks); | |
202 EXPECT_LT(kDelay, time_after_run - time_before_run); | |
203 } | |
204 | |
205 void RunTest_PostDelayedTask_InDelayOrder( | |
206 MessageLoop::Type message_loop_type) { | |
207 MessageLoop loop(message_loop_type); | |
208 | |
209 // Test that two tasks with different delays run in the right order. | |
210 int num_tasks = 2; | |
211 Time run_time1, run_time2; | |
212 | |
213 loop.PostDelayedTask( | |
214 FROM_HERE, | |
215 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), | |
216 TimeDelta::FromMilliseconds(200)); | |
217 // If we get a large pause in execution (due to a context switch) here, this | |
218 // test could fail. | |
219 loop.PostDelayedTask( | |
220 FROM_HERE, | |
221 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | |
222 TimeDelta::FromMilliseconds(10)); | |
223 | |
224 loop.Run(); | |
225 EXPECT_EQ(0, num_tasks); | |
226 | |
227 EXPECT_TRUE(run_time2 < run_time1); | |
228 } | |
229 | |
230 void RunTest_PostDelayedTask_InPostOrder( | |
231 MessageLoop::Type message_loop_type) { | |
232 MessageLoop loop(message_loop_type); | |
233 | |
234 // Test that two tasks with the same delay run in the order in which they | |
235 // were posted. | |
236 // | |
237 // NOTE: This is actually an approximate test since the API only takes a | |
238 // "delay" parameter, so we are not exactly simulating two tasks that get | |
239 // posted at the exact same time. It would be nice if the API allowed us to | |
240 // specify the desired run time. | |
241 | |
242 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); | |
243 | |
244 int num_tasks = 2; | |
245 Time run_time1, run_time2; | |
246 | |
247 loop.PostDelayedTask( | |
248 FROM_HERE, | |
249 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), kDelay); | |
250 loop.PostDelayedTask( | |
251 FROM_HERE, | |
252 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), kDelay); | |
253 | |
254 loop.Run(); | |
255 EXPECT_EQ(0, num_tasks); | |
256 | |
257 EXPECT_TRUE(run_time1 < run_time2); | |
258 } | |
259 | |
260 void RunTest_PostDelayedTask_InPostOrder_2( | |
261 MessageLoop::Type message_loop_type) { | |
262 MessageLoop loop(message_loop_type); | |
263 | |
264 // Test that a delayed task still runs after a normal tasks even if the | |
265 // normal tasks take a long time to run. | |
266 | |
267 const TimeDelta kPause = TimeDelta::FromMilliseconds(50); | |
268 | |
269 int num_tasks = 2; | |
270 Time run_time; | |
271 | |
272 loop.PostTask(FROM_HERE, Bind(&SlowFunc, kPause, &num_tasks)); | |
273 loop.PostDelayedTask( | |
274 FROM_HERE, | |
275 Bind(&RecordRunTimeFunc, &run_time, &num_tasks), | |
276 TimeDelta::FromMilliseconds(10)); | |
277 | |
278 Time time_before_run = Time::Now(); | |
279 loop.Run(); | |
280 Time time_after_run = Time::Now(); | |
281 | |
282 EXPECT_EQ(0, num_tasks); | |
283 | |
284 EXPECT_LT(kPause, time_after_run - time_before_run); | |
285 } | |
286 | |
287 void RunTest_PostDelayedTask_InPostOrder_3( | |
288 MessageLoop::Type message_loop_type) { | |
289 MessageLoop loop(message_loop_type); | |
290 | |
291 // Test that a delayed task still runs after a pile of normal tasks. The key | |
292 // difference between this test and the previous one is that here we return | |
293 // the MessageLoop a lot so we give the MessageLoop plenty of opportunities | |
294 // to maybe run the delayed task. It should know not to do so until the | |
295 // delayed task's delay has passed. | |
296 | |
297 int num_tasks = 11; | |
298 Time run_time1, run_time2; | |
299 | |
300 // Clutter the ML with tasks. | |
301 for (int i = 1; i < num_tasks; ++i) | |
302 loop.PostTask(FROM_HERE, | |
303 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks)); | |
304 | |
305 loop.PostDelayedTask( | |
306 FROM_HERE, Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | |
307 TimeDelta::FromMilliseconds(1)); | |
308 | |
309 loop.Run(); | |
310 EXPECT_EQ(0, num_tasks); | |
311 | |
312 EXPECT_TRUE(run_time2 > run_time1); | |
313 } | |
314 | |
315 void RunTest_PostDelayedTask_SharedTimer( | |
316 MessageLoop::Type message_loop_type) { | |
317 MessageLoop loop(message_loop_type); | |
318 | |
319 // Test that the interval of the timer, used to run the next delayed task, is | |
320 // set to a value corresponding to when the next delayed task should run. | |
321 | |
322 // By setting num_tasks to 1, we ensure that the first task to run causes the | |
323 // run loop to exit. | |
324 int num_tasks = 1; | |
325 Time run_time1, run_time2; | |
326 | |
327 loop.PostDelayedTask( | |
328 FROM_HERE, | |
329 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), | |
330 TimeDelta::FromSeconds(1000)); | |
331 loop.PostDelayedTask( | |
332 FROM_HERE, | |
333 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | |
334 TimeDelta::FromMilliseconds(10)); | |
335 | |
336 Time start_time = Time::Now(); | |
337 | |
338 loop.Run(); | |
339 EXPECT_EQ(0, num_tasks); | |
340 | |
341 // Ensure that we ran in far less time than the slower timer. | |
342 TimeDelta total_time = Time::Now() - start_time; | |
343 EXPECT_GT(5000, total_time.InMilliseconds()); | |
344 | |
345 // In case both timers somehow run at nearly the same time, sleep a little | |
346 // and then run all pending to force them both to have run. This is just | |
347 // encouraging flakiness if there is any. | |
348 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); | |
349 RunLoop().RunUntilIdle(); | |
350 | |
351 EXPECT_TRUE(run_time1.is_null()); | |
352 EXPECT_FALSE(run_time2.is_null()); | |
353 } | |
354 | |
355 #if defined(OS_WIN) | |
356 | |
357 void SubPumpFunc() { | 115 void SubPumpFunc() { |
358 MessageLoop::current()->SetNestableTasksAllowed(true); | 116 MessageLoop::current()->SetNestableTasksAllowed(true); |
359 MSG msg; | 117 MSG msg; |
360 while (GetMessage(&msg, NULL, 0, 0)) { | 118 while (GetMessage(&msg, NULL, 0, 0)) { |
361 TranslateMessage(&msg); | 119 TranslateMessage(&msg); |
362 DispatchMessage(&msg); | 120 DispatchMessage(&msg); |
363 } | 121 } |
364 MessageLoop::current()->QuitWhenIdle(); | 122 MessageLoop::current()->QuitWhenIdle(); |
365 } | 123 } |
366 | 124 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 | 158 |
401 // In case both timers somehow run at nearly the same time, sleep a little | 159 // In case both timers somehow run at nearly the same time, sleep a little |
402 // and then run all pending to force them both to have run. This is just | 160 // and then run all pending to force them both to have run. This is just |
403 // encouraging flakiness if there is any. | 161 // encouraging flakiness if there is any. |
404 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); | 162 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); |
405 RunLoop().RunUntilIdle(); | 163 RunLoop().RunUntilIdle(); |
406 | 164 |
407 EXPECT_TRUE(run_time.is_null()); | 165 EXPECT_TRUE(run_time.is_null()); |
408 } | 166 } |
409 | 167 |
410 #endif // defined(OS_WIN) | |
411 | |
412 // This is used to inject a test point for recording the destructor calls for | |
413 // Closure objects send to MessageLoop::PostTask(). It is awkward usage since we | |
414 // are trying to hook the actual destruction, which is not a common operation. | |
415 class RecordDeletionProbe : public RefCounted<RecordDeletionProbe> { | |
416 public: | |
417 RecordDeletionProbe(RecordDeletionProbe* post_on_delete, bool* was_deleted) | |
418 : post_on_delete_(post_on_delete), was_deleted_(was_deleted) { | |
419 } | |
420 void Run() {} | |
421 | |
422 private: | |
423 friend class RefCounted<RecordDeletionProbe>; | |
424 | |
425 ~RecordDeletionProbe() { | |
426 *was_deleted_ = true; | |
427 if (post_on_delete_.get()) | |
428 MessageLoop::current()->PostTask( | |
429 FROM_HERE, Bind(&RecordDeletionProbe::Run, post_on_delete_.get())); | |
430 } | |
431 | |
432 scoped_refptr<RecordDeletionProbe> post_on_delete_; | |
433 bool* was_deleted_; | |
434 }; | |
435 | |
436 void RunTest_EnsureDeletion(MessageLoop::Type message_loop_type) { | |
437 bool a_was_deleted = false; | |
438 bool b_was_deleted = false; | |
439 { | |
440 MessageLoop loop(message_loop_type); | |
441 loop.PostTask( | |
442 FROM_HERE, Bind(&RecordDeletionProbe::Run, | |
443 new RecordDeletionProbe(NULL, &a_was_deleted))); | |
444 // TODO(ajwong): Do we really need 1000ms here? | |
445 loop.PostDelayedTask( | |
446 FROM_HERE, Bind(&RecordDeletionProbe::Run, | |
447 new RecordDeletionProbe(NULL, &b_was_deleted)), | |
448 TimeDelta::FromMilliseconds(1000)); | |
449 } | |
450 EXPECT_TRUE(a_was_deleted); | |
451 EXPECT_TRUE(b_was_deleted); | |
452 } | |
453 | |
454 void RunTest_EnsureDeletion_Chain(MessageLoop::Type message_loop_type) { | |
455 bool a_was_deleted = false; | |
456 bool b_was_deleted = false; | |
457 bool c_was_deleted = false; | |
458 { | |
459 MessageLoop loop(message_loop_type); | |
460 // The scoped_refptr for each of the below is held either by the chained | |
461 // RecordDeletionProbe, or the bound RecordDeletionProbe::Run() callback. | |
462 RecordDeletionProbe* a = new RecordDeletionProbe(NULL, &a_was_deleted); | |
463 RecordDeletionProbe* b = new RecordDeletionProbe(a, &b_was_deleted); | |
464 RecordDeletionProbe* c = new RecordDeletionProbe(b, &c_was_deleted); | |
465 loop.PostTask(FROM_HERE, Bind(&RecordDeletionProbe::Run, c)); | |
466 } | |
467 EXPECT_TRUE(a_was_deleted); | |
468 EXPECT_TRUE(b_was_deleted); | |
469 EXPECT_TRUE(c_was_deleted); | |
470 } | |
471 | |
472 void NestingFunc(int* depth) { | |
473 if (*depth > 0) { | |
474 *depth -= 1; | |
475 MessageLoop::current()->PostTask(FROM_HERE, | |
476 Bind(&NestingFunc, depth)); | |
477 | |
478 MessageLoop::current()->SetNestableTasksAllowed(true); | |
479 MessageLoop::current()->Run(); | |
480 } | |
481 MessageLoop::current()->QuitWhenIdle(); | |
482 } | |
483 | |
484 #if defined(OS_WIN) | |
485 | |
486 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) { | 168 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) { |
487 ADD_FAILURE() << "bad exception handler"; | 169 ADD_FAILURE() << "bad exception handler"; |
488 ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode); | 170 ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode); |
489 return EXCEPTION_EXECUTE_HANDLER; | 171 return EXCEPTION_EXECUTE_HANDLER; |
490 } | 172 } |
491 | 173 |
492 // This task throws an SEH exception: initially write to an invalid address. | 174 // This task throws an SEH exception: initially write to an invalid address. |
493 // If the right SEH filter is installed, it will fix the error. | 175 // If the right SEH filter is installed, it will fix the error. |
494 class Crasher : public RefCounted<Crasher> { | 176 class Crasher : public RefCounted<Crasher> { |
495 public: | 177 public: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 MessageLoop::current()->PostTask( | 272 MessageLoop::current()->PostTask( |
591 FROM_HERE, | 273 FROM_HERE, |
592 Bind(&Crasher::Run, new Crasher(true))); | 274 Bind(&Crasher::Run, new Crasher(true))); |
593 MessageLoop::current()->set_exception_restoration(true); | 275 MessageLoop::current()->set_exception_restoration(true); |
594 MessageLoop::current()->Run(); | 276 MessageLoop::current()->Run(); |
595 MessageLoop::current()->set_exception_restoration(false); | 277 MessageLoop::current()->set_exception_restoration(false); |
596 | 278 |
597 ::SetUnhandledExceptionFilter(old_SEH_filter); | 279 ::SetUnhandledExceptionFilter(old_SEH_filter); |
598 } | 280 } |
599 | 281 |
600 #endif // defined(OS_WIN) | |
601 | |
602 void RunTest_Nesting(MessageLoop::Type message_loop_type) { | |
603 MessageLoop loop(message_loop_type); | |
604 | |
605 int depth = 100; | |
606 MessageLoop::current()->PostTask(FROM_HERE, | |
607 Bind(&NestingFunc, &depth)); | |
608 MessageLoop::current()->Run(); | |
609 EXPECT_EQ(depth, 0); | |
610 } | |
611 | |
612 #if defined(OS_WIN) | |
613 const wchar_t kMessageBoxTitle[] = L"MessageLoop Unit Test"; | 282 const wchar_t kMessageBoxTitle[] = L"MessageLoop Unit Test"; |
614 #endif // defined(OS_WIN) | |
615 | 283 |
616 enum TaskType { | 284 enum TaskType { |
617 MESSAGEBOX, | 285 MESSAGEBOX, |
618 ENDDIALOG, | 286 ENDDIALOG, |
619 RECURSIVE, | 287 RECURSIVE, |
620 TIMEDMESSAGELOOP, | 288 TIMEDMESSAGELOOP, |
621 QUITMESSAGELOOP, | 289 QUITMESSAGELOOP, |
622 ORDERED, | 290 ORDERED, |
623 PUMPS, | 291 PUMPS, |
624 SLEEP, | 292 SLEEP, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 } | 354 } |
687 | 355 |
688 TaskItem Get(int n) { | 356 TaskItem Get(int n) { |
689 return task_list_[n]; | 357 return task_list_[n]; |
690 } | 358 } |
691 | 359 |
692 private: | 360 private: |
693 std::vector<TaskItem> task_list_; | 361 std::vector<TaskItem> task_list_; |
694 }; | 362 }; |
695 | 363 |
696 // Saves the order the tasks ran. | |
697 void OrderedFunc(TaskList* order, int cookie) { | |
698 order->RecordStart(ORDERED, cookie); | |
699 order->RecordEnd(ORDERED, cookie); | |
700 } | |
701 | |
702 #if defined(OS_WIN) | |
703 | |
704 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes, | 364 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes, |
705 // common controls (like OpenFile) and StartDoc printing function can cause | 365 // common controls (like OpenFile) and StartDoc printing function can cause |
706 // implicit message loops. | 366 // implicit message loops. |
707 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) { | 367 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) { |
708 order->RecordStart(MESSAGEBOX, cookie); | 368 order->RecordStart(MESSAGEBOX, cookie); |
709 if (is_reentrant) | 369 if (is_reentrant) |
710 MessageLoop::current()->SetNestableTasksAllowed(true); | 370 MessageLoop::current()->SetNestableTasksAllowed(true); |
711 MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK); | 371 MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK); |
712 order->RecordEnd(MESSAGEBOX, cookie); | 372 order->RecordEnd(MESSAGEBOX, cookie); |
713 } | 373 } |
714 | 374 |
715 // Will end the MessageBox. | 375 // Will end the MessageBox. |
716 void EndDialogFunc(TaskList* order, int cookie) { | 376 void EndDialogFunc(TaskList* order, int cookie) { |
717 order->RecordStart(ENDDIALOG, cookie); | 377 order->RecordStart(ENDDIALOG, cookie); |
718 HWND window = GetActiveWindow(); | 378 HWND window = GetActiveWindow(); |
719 if (window != NULL) { | 379 if (window != NULL) { |
720 EXPECT_NE(EndDialog(window, IDCONTINUE), 0); | 380 EXPECT_NE(EndDialog(window, IDCONTINUE), 0); |
721 // Cheap way to signal that the window wasn't found if RunEnd() isn't | 381 // Cheap way to signal that the window wasn't found if RunEnd() isn't |
722 // called. | 382 // called. |
723 order->RecordEnd(ENDDIALOG, cookie); | 383 order->RecordEnd(ENDDIALOG, cookie); |
724 } | 384 } |
725 } | 385 } |
726 | 386 |
727 #endif // defined(OS_WIN) | |
728 | |
729 void RecursiveFunc(TaskList* order, int cookie, int depth, | 387 void RecursiveFunc(TaskList* order, int cookie, int depth, |
730 bool is_reentrant) { | 388 bool is_reentrant) { |
731 order->RecordStart(RECURSIVE, cookie); | 389 order->RecordStart(RECURSIVE, cookie); |
732 if (depth > 0) { | 390 if (depth > 0) { |
733 if (is_reentrant) | 391 if (is_reentrant) |
734 MessageLoop::current()->SetNestableTasksAllowed(true); | 392 MessageLoop::current()->SetNestableTasksAllowed(true); |
735 MessageLoop::current()->PostTask( | 393 MessageLoop::current()->PostTask( |
736 FROM_HERE, | 394 FROM_HERE, |
737 Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant)); | 395 Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant)); |
738 } | 396 } |
739 order->RecordEnd(RECURSIVE, cookie); | 397 order->RecordEnd(RECURSIVE, cookie); |
740 } | 398 } |
741 | 399 |
742 void RecursiveSlowFunc(TaskList* order, int cookie, int depth, | |
743 bool is_reentrant) { | |
744 RecursiveFunc(order, cookie, depth, is_reentrant); | |
745 PlatformThread::Sleep(TimeDelta::FromMilliseconds(10)); | |
746 } | |
747 | |
748 void QuitFunc(TaskList* order, int cookie) { | 400 void QuitFunc(TaskList* order, int cookie) { |
749 order->RecordStart(QUITMESSAGELOOP, cookie); | 401 order->RecordStart(QUITMESSAGELOOP, cookie); |
750 MessageLoop::current()->QuitWhenIdle(); | 402 MessageLoop::current()->QuitWhenIdle(); |
751 order->RecordEnd(QUITMESSAGELOOP, cookie); | 403 order->RecordEnd(QUITMESSAGELOOP, cookie); |
752 } | 404 } |
753 | 405 |
754 void SleepFunc(TaskList* order, int cookie, TimeDelta delay) { | |
755 order->RecordStart(SLEEP, cookie); | |
756 PlatformThread::Sleep(delay); | |
757 order->RecordEnd(SLEEP, cookie); | |
758 } | |
759 | |
760 #if defined(OS_WIN) | |
761 void RecursiveFuncWin(MessageLoop* target, | 406 void RecursiveFuncWin(MessageLoop* target, |
762 HANDLE event, | 407 HANDLE event, |
763 bool expect_window, | 408 bool expect_window, |
764 TaskList* order, | 409 TaskList* order, |
765 bool is_reentrant) { | 410 bool is_reentrant) { |
766 target->PostTask(FROM_HERE, | 411 target->PostTask(FROM_HERE, |
767 Bind(&RecursiveFunc, order, 1, 2, is_reentrant)); | 412 Bind(&RecursiveFunc, order, 1, 2, is_reentrant)); |
768 target->PostTask(FROM_HERE, | 413 target->PostTask(FROM_HERE, |
769 Bind(&MessageBoxFunc, order, 2, is_reentrant)); | 414 Bind(&MessageBoxFunc, order, 2, is_reentrant)); |
770 target->PostTask(FROM_HERE, | 415 target->PostTask(FROM_HERE, |
(...skipping 25 matching lines...) Expand all Loading... |
796 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0)); | 441 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0)); |
797 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0)); | 442 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0)); |
798 break; | 443 break; |
799 } | 444 } |
800 } | 445 } |
801 break; | 446 break; |
802 } | 447 } |
803 } | 448 } |
804 } | 449 } |
805 | 450 |
806 #endif // defined(OS_WIN) | |
807 | |
808 void RunTest_RecursiveDenial1(MessageLoop::Type message_loop_type) { | |
809 MessageLoop loop(message_loop_type); | |
810 | |
811 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); | |
812 TaskList order; | |
813 MessageLoop::current()->PostTask( | |
814 FROM_HERE, | |
815 Bind(&RecursiveFunc, &order, 1, 2, false)); | |
816 MessageLoop::current()->PostTask( | |
817 FROM_HERE, | |
818 Bind(&RecursiveFunc, &order, 2, 2, false)); | |
819 MessageLoop::current()->PostTask( | |
820 FROM_HERE, | |
821 Bind(&QuitFunc, &order, 3)); | |
822 | |
823 MessageLoop::current()->Run(); | |
824 | |
825 // FIFO order. | |
826 ASSERT_EQ(14U, order.Size()); | |
827 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | |
828 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | |
829 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | |
830 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | |
831 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | |
832 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); | |
833 EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true)); | |
834 EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false)); | |
835 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); | |
836 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); | |
837 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); | |
838 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); | |
839 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true)); | |
840 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false)); | |
841 } | |
842 | |
843 void RunTest_RecursiveDenial3(MessageLoop::Type message_loop_type) { | |
844 MessageLoop loop(message_loop_type); | |
845 | |
846 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); | |
847 TaskList order; | |
848 MessageLoop::current()->PostTask( | |
849 FROM_HERE, Bind(&RecursiveSlowFunc, &order, 1, 2, false)); | |
850 MessageLoop::current()->PostTask( | |
851 FROM_HERE, Bind(&RecursiveSlowFunc, &order, 2, 2, false)); | |
852 MessageLoop::current()->PostDelayedTask( | |
853 FROM_HERE, | |
854 Bind(&OrderedFunc, &order, 3), | |
855 TimeDelta::FromMilliseconds(5)); | |
856 MessageLoop::current()->PostDelayedTask( | |
857 FROM_HERE, | |
858 Bind(&QuitFunc, &order, 4), | |
859 TimeDelta::FromMilliseconds(5)); | |
860 | |
861 MessageLoop::current()->Run(); | |
862 | |
863 // FIFO order. | |
864 ASSERT_EQ(16U, order.Size()); | |
865 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | |
866 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | |
867 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | |
868 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | |
869 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 1, true)); | |
870 EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 1, false)); | |
871 EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 3, true)); | |
872 EXPECT_EQ(order.Get(7), TaskItem(ORDERED, 3, false)); | |
873 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); | |
874 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); | |
875 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 4, true)); | |
876 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 4, false)); | |
877 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 1, true)); | |
878 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, false)); | |
879 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 2, true)); | |
880 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 2, false)); | |
881 } | |
882 | |
883 void RunTest_RecursiveSupport1(MessageLoop::Type message_loop_type) { | |
884 MessageLoop loop(message_loop_type); | |
885 | |
886 TaskList order; | |
887 MessageLoop::current()->PostTask( | |
888 FROM_HERE, Bind(&RecursiveFunc, &order, 1, 2, true)); | |
889 MessageLoop::current()->PostTask( | |
890 FROM_HERE, Bind(&RecursiveFunc, &order, 2, 2, true)); | |
891 MessageLoop::current()->PostTask( | |
892 FROM_HERE, Bind(&QuitFunc, &order, 3)); | |
893 | |
894 MessageLoop::current()->Run(); | |
895 | |
896 // FIFO order. | |
897 ASSERT_EQ(14U, order.Size()); | |
898 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | |
899 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | |
900 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | |
901 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | |
902 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | |
903 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); | |
904 EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true)); | |
905 EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false)); | |
906 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); | |
907 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); | |
908 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); | |
909 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); | |
910 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true)); | |
911 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false)); | |
912 } | |
913 | |
914 #if defined(OS_WIN) | |
915 // TODO(darin): These tests need to be ported since they test critical | 451 // TODO(darin): These tests need to be ported since they test critical |
916 // message loop functionality. | 452 // message loop functionality. |
917 | 453 |
918 // A side effect of this test is the generation a beep. Sorry. | 454 // A side effect of this test is the generation a beep. Sorry. |
919 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { | 455 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { |
920 MessageLoop loop(message_loop_type); | 456 MessageLoop loop(message_loop_type); |
921 | 457 |
922 Thread worker("RecursiveDenial2_worker"); | 458 Thread worker("RecursiveDenial2_worker"); |
923 Thread::Options options; | 459 Thread::Options options; |
924 options.message_loop_type = message_loop_type; | 460 options.message_loop_type = message_loop_type; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true)); | 538 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true)); |
1003 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false)); | 539 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false)); |
1004 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true)); | 540 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true)); |
1005 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false)); | 541 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false)); |
1006 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true)); | 542 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true)); |
1007 EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false)); | 543 EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false)); |
1008 } | 544 } |
1009 | 545 |
1010 #endif // defined(OS_WIN) | 546 #endif // defined(OS_WIN) |
1011 | 547 |
1012 void FuncThatPumps(TaskList* order, int cookie) { | |
1013 order->RecordStart(PUMPS, cookie); | |
1014 { | |
1015 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); | |
1016 RunLoop().RunUntilIdle(); | |
1017 } | |
1018 order->RecordEnd(PUMPS, cookie); | |
1019 } | |
1020 | |
1021 void FuncThatRuns(TaskList* order, int cookie, RunLoop* run_loop) { | |
1022 order->RecordStart(RUNS, cookie); | |
1023 { | |
1024 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); | |
1025 run_loop->Run(); | |
1026 } | |
1027 order->RecordEnd(RUNS, cookie); | |
1028 } | |
1029 | |
1030 void FuncThatQuitsNow() { | |
1031 MessageLoop::current()->QuitNow(); | |
1032 } | |
1033 | |
1034 // Tests that non nestable tasks run in FIFO if there are no nested loops. | |
1035 void RunTest_NonNestableWithNoNesting( | |
1036 MessageLoop::Type message_loop_type) { | |
1037 MessageLoop loop(message_loop_type); | |
1038 | |
1039 TaskList order; | |
1040 | |
1041 MessageLoop::current()->PostNonNestableTask( | |
1042 FROM_HERE, | |
1043 Bind(&OrderedFunc, &order, 1)); | |
1044 MessageLoop::current()->PostTask(FROM_HERE, | |
1045 Bind(&OrderedFunc, &order, 2)); | |
1046 MessageLoop::current()->PostTask(FROM_HERE, | |
1047 Bind(&QuitFunc, &order, 3)); | |
1048 MessageLoop::current()->Run(); | |
1049 | |
1050 // FIFO order. | |
1051 ASSERT_EQ(6U, order.Size()); | |
1052 EXPECT_EQ(order.Get(0), TaskItem(ORDERED, 1, true)); | |
1053 EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 1, false)); | |
1054 EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 2, true)); | |
1055 EXPECT_EQ(order.Get(3), TaskItem(ORDERED, 2, false)); | |
1056 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | |
1057 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); | |
1058 } | |
1059 | |
1060 // Tests that non nestable tasks don't run when there's code in the call stack. | |
1061 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type, | |
1062 bool use_delayed) { | |
1063 MessageLoop loop(message_loop_type); | |
1064 | |
1065 TaskList order; | |
1066 | |
1067 MessageLoop::current()->PostTask( | |
1068 FROM_HERE, | |
1069 Bind(&FuncThatPumps, &order, 1)); | |
1070 if (use_delayed) { | |
1071 MessageLoop::current()->PostNonNestableDelayedTask( | |
1072 FROM_HERE, | |
1073 Bind(&OrderedFunc, &order, 2), | |
1074 TimeDelta::FromMilliseconds(1)); | |
1075 } else { | |
1076 MessageLoop::current()->PostNonNestableTask( | |
1077 FROM_HERE, | |
1078 Bind(&OrderedFunc, &order, 2)); | |
1079 } | |
1080 MessageLoop::current()->PostTask(FROM_HERE, | |
1081 Bind(&OrderedFunc, &order, 3)); | |
1082 MessageLoop::current()->PostTask( | |
1083 FROM_HERE, | |
1084 Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50))); | |
1085 MessageLoop::current()->PostTask(FROM_HERE, | |
1086 Bind(&OrderedFunc, &order, 5)); | |
1087 if (use_delayed) { | |
1088 MessageLoop::current()->PostNonNestableDelayedTask( | |
1089 FROM_HERE, | |
1090 Bind(&QuitFunc, &order, 6), | |
1091 TimeDelta::FromMilliseconds(2)); | |
1092 } else { | |
1093 MessageLoop::current()->PostNonNestableTask( | |
1094 FROM_HERE, | |
1095 Bind(&QuitFunc, &order, 6)); | |
1096 } | |
1097 | |
1098 MessageLoop::current()->Run(); | |
1099 | |
1100 // FIFO order. | |
1101 ASSERT_EQ(12U, order.Size()); | |
1102 EXPECT_EQ(order.Get(0), TaskItem(PUMPS, 1, true)); | |
1103 EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 3, true)); | |
1104 EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 3, false)); | |
1105 EXPECT_EQ(order.Get(3), TaskItem(SLEEP, 4, true)); | |
1106 EXPECT_EQ(order.Get(4), TaskItem(SLEEP, 4, false)); | |
1107 EXPECT_EQ(order.Get(5), TaskItem(ORDERED, 5, true)); | |
1108 EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 5, false)); | |
1109 EXPECT_EQ(order.Get(7), TaskItem(PUMPS, 1, false)); | |
1110 EXPECT_EQ(order.Get(8), TaskItem(ORDERED, 2, true)); | |
1111 EXPECT_EQ(order.Get(9), TaskItem(ORDERED, 2, false)); | |
1112 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 6, true)); | |
1113 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 6, false)); | |
1114 } | |
1115 | |
1116 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
1117 void RunTest_QuitNow(MessageLoop::Type message_loop_type) { | |
1118 MessageLoop loop(message_loop_type); | |
1119 | |
1120 TaskList order; | |
1121 | |
1122 RunLoop run_loop; | |
1123 | |
1124 MessageLoop::current()->PostTask(FROM_HERE, | |
1125 Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop))); | |
1126 MessageLoop::current()->PostTask( | |
1127 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
1128 MessageLoop::current()->PostTask( | |
1129 FROM_HERE, Bind(&FuncThatQuitsNow)); | |
1130 MessageLoop::current()->PostTask( | |
1131 FROM_HERE, Bind(&OrderedFunc, &order, 3)); | |
1132 MessageLoop::current()->PostTask( | |
1133 FROM_HERE, Bind(&FuncThatQuitsNow)); | |
1134 MessageLoop::current()->PostTask( | |
1135 FROM_HERE, Bind(&OrderedFunc, &order, 4)); // never runs | |
1136 | |
1137 MessageLoop::current()->Run(); | |
1138 | |
1139 ASSERT_EQ(6U, order.Size()); | |
1140 int task_index = 0; | |
1141 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
1142 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
1143 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
1144 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
1145 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true)); | |
1146 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false)); | |
1147 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
1148 } | |
1149 | |
1150 // Tests RunLoopQuit works before RunWithID. | |
1151 void RunTest_RunLoopQuitOrderBefore(MessageLoop::Type message_loop_type) { | |
1152 MessageLoop loop(message_loop_type); | |
1153 | |
1154 TaskList order; | |
1155 | |
1156 RunLoop run_loop; | |
1157 | |
1158 run_loop.Quit(); | |
1159 | |
1160 MessageLoop::current()->PostTask( | |
1161 FROM_HERE, Bind(&OrderedFunc, &order, 1)); // never runs | |
1162 MessageLoop::current()->PostTask( | |
1163 FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs | |
1164 | |
1165 run_loop.Run(); | |
1166 | |
1167 ASSERT_EQ(0U, order.Size()); | |
1168 } | |
1169 | |
1170 // Tests RunLoopQuit works during RunWithID. | |
1171 void RunTest_RunLoopQuitOrderDuring(MessageLoop::Type message_loop_type) { | |
1172 MessageLoop loop(message_loop_type); | |
1173 | |
1174 TaskList order; | |
1175 | |
1176 RunLoop run_loop; | |
1177 | |
1178 MessageLoop::current()->PostTask( | |
1179 FROM_HERE, Bind(&OrderedFunc, &order, 1)); | |
1180 MessageLoop::current()->PostTask( | |
1181 FROM_HERE, run_loop.QuitClosure()); | |
1182 MessageLoop::current()->PostTask( | |
1183 FROM_HERE, Bind(&OrderedFunc, &order, 2)); // never runs | |
1184 MessageLoop::current()->PostTask( | |
1185 FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs | |
1186 | |
1187 run_loop.Run(); | |
1188 | |
1189 ASSERT_EQ(2U, order.Size()); | |
1190 int task_index = 0; | |
1191 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, true)); | |
1192 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, false)); | |
1193 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
1194 } | |
1195 | |
1196 // Tests RunLoopQuit works after RunWithID. | |
1197 void RunTest_RunLoopQuitOrderAfter(MessageLoop::Type message_loop_type) { | |
1198 MessageLoop loop(message_loop_type); | |
1199 | |
1200 TaskList order; | |
1201 | |
1202 RunLoop run_loop; | |
1203 | |
1204 MessageLoop::current()->PostTask(FROM_HERE, | |
1205 Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop))); | |
1206 MessageLoop::current()->PostTask( | |
1207 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
1208 MessageLoop::current()->PostTask( | |
1209 FROM_HERE, Bind(&FuncThatQuitsNow)); | |
1210 MessageLoop::current()->PostTask( | |
1211 FROM_HERE, Bind(&OrderedFunc, &order, 3)); | |
1212 MessageLoop::current()->PostTask( | |
1213 FROM_HERE, run_loop.QuitClosure()); // has no affect | |
1214 MessageLoop::current()->PostTask( | |
1215 FROM_HERE, Bind(&OrderedFunc, &order, 4)); | |
1216 MessageLoop::current()->PostTask( | |
1217 FROM_HERE, Bind(&FuncThatQuitsNow)); | |
1218 | |
1219 RunLoop outer_run_loop; | |
1220 outer_run_loop.Run(); | |
1221 | |
1222 ASSERT_EQ(8U, order.Size()); | |
1223 int task_index = 0; | |
1224 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
1225 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
1226 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
1227 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
1228 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true)); | |
1229 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false)); | |
1230 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, true)); | |
1231 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, false)); | |
1232 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
1233 } | |
1234 | |
1235 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
1236 void RunTest_RunLoopQuitTop(MessageLoop::Type message_loop_type) { | |
1237 MessageLoop loop(message_loop_type); | |
1238 | |
1239 TaskList order; | |
1240 | |
1241 RunLoop outer_run_loop; | |
1242 RunLoop nested_run_loop; | |
1243 | |
1244 MessageLoop::current()->PostTask(FROM_HERE, | |
1245 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); | |
1246 MessageLoop::current()->PostTask( | |
1247 FROM_HERE, outer_run_loop.QuitClosure()); | |
1248 MessageLoop::current()->PostTask( | |
1249 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
1250 MessageLoop::current()->PostTask( | |
1251 FROM_HERE, nested_run_loop.QuitClosure()); | |
1252 | |
1253 outer_run_loop.Run(); | |
1254 | |
1255 ASSERT_EQ(4U, order.Size()); | |
1256 int task_index = 0; | |
1257 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
1258 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
1259 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
1260 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
1261 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
1262 } | |
1263 | |
1264 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
1265 void RunTest_RunLoopQuitNested(MessageLoop::Type message_loop_type) { | |
1266 MessageLoop loop(message_loop_type); | |
1267 | |
1268 TaskList order; | |
1269 | |
1270 RunLoop outer_run_loop; | |
1271 RunLoop nested_run_loop; | |
1272 | |
1273 MessageLoop::current()->PostTask(FROM_HERE, | |
1274 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); | |
1275 MessageLoop::current()->PostTask( | |
1276 FROM_HERE, nested_run_loop.QuitClosure()); | |
1277 MessageLoop::current()->PostTask( | |
1278 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
1279 MessageLoop::current()->PostTask( | |
1280 FROM_HERE, outer_run_loop.QuitClosure()); | |
1281 | |
1282 outer_run_loop.Run(); | |
1283 | |
1284 ASSERT_EQ(4U, order.Size()); | |
1285 int task_index = 0; | |
1286 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
1287 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
1288 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
1289 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
1290 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
1291 } | |
1292 | |
1293 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
1294 void RunTest_RunLoopQuitBogus(MessageLoop::Type message_loop_type) { | |
1295 MessageLoop loop(message_loop_type); | |
1296 | |
1297 TaskList order; | |
1298 | |
1299 RunLoop outer_run_loop; | |
1300 RunLoop nested_run_loop; | |
1301 RunLoop bogus_run_loop; | |
1302 | |
1303 MessageLoop::current()->PostTask(FROM_HERE, | |
1304 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); | |
1305 MessageLoop::current()->PostTask( | |
1306 FROM_HERE, bogus_run_loop.QuitClosure()); | |
1307 MessageLoop::current()->PostTask( | |
1308 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
1309 MessageLoop::current()->PostTask( | |
1310 FROM_HERE, outer_run_loop.QuitClosure()); | |
1311 MessageLoop::current()->PostTask( | |
1312 FROM_HERE, nested_run_loop.QuitClosure()); | |
1313 | |
1314 outer_run_loop.Run(); | |
1315 | |
1316 ASSERT_EQ(4U, order.Size()); | |
1317 int task_index = 0; | |
1318 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
1319 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
1320 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
1321 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
1322 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
1323 } | |
1324 | |
1325 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
1326 void RunTest_RunLoopQuitDeep(MessageLoop::Type message_loop_type) { | |
1327 MessageLoop loop(message_loop_type); | |
1328 | |
1329 TaskList order; | |
1330 | |
1331 RunLoop outer_run_loop; | |
1332 RunLoop nested_loop1; | |
1333 RunLoop nested_loop2; | |
1334 RunLoop nested_loop3; | |
1335 RunLoop nested_loop4; | |
1336 | |
1337 MessageLoop::current()->PostTask(FROM_HERE, | |
1338 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_loop1))); | |
1339 MessageLoop::current()->PostTask(FROM_HERE, | |
1340 Bind(&FuncThatRuns, &order, 2, Unretained(&nested_loop2))); | |
1341 MessageLoop::current()->PostTask(FROM_HERE, | |
1342 Bind(&FuncThatRuns, &order, 3, Unretained(&nested_loop3))); | |
1343 MessageLoop::current()->PostTask(FROM_HERE, | |
1344 Bind(&FuncThatRuns, &order, 4, Unretained(&nested_loop4))); | |
1345 MessageLoop::current()->PostTask( | |
1346 FROM_HERE, Bind(&OrderedFunc, &order, 5)); | |
1347 MessageLoop::current()->PostTask( | |
1348 FROM_HERE, outer_run_loop.QuitClosure()); | |
1349 MessageLoop::current()->PostTask( | |
1350 FROM_HERE, Bind(&OrderedFunc, &order, 6)); | |
1351 MessageLoop::current()->PostTask( | |
1352 FROM_HERE, nested_loop1.QuitClosure()); | |
1353 MessageLoop::current()->PostTask( | |
1354 FROM_HERE, Bind(&OrderedFunc, &order, 7)); | |
1355 MessageLoop::current()->PostTask( | |
1356 FROM_HERE, nested_loop2.QuitClosure()); | |
1357 MessageLoop::current()->PostTask( | |
1358 FROM_HERE, Bind(&OrderedFunc, &order, 8)); | |
1359 MessageLoop::current()->PostTask( | |
1360 FROM_HERE, nested_loop3.QuitClosure()); | |
1361 MessageLoop::current()->PostTask( | |
1362 FROM_HERE, Bind(&OrderedFunc, &order, 9)); | |
1363 MessageLoop::current()->PostTask( | |
1364 FROM_HERE, nested_loop4.QuitClosure()); | |
1365 MessageLoop::current()->PostTask( | |
1366 FROM_HERE, Bind(&OrderedFunc, &order, 10)); | |
1367 | |
1368 outer_run_loop.Run(); | |
1369 | |
1370 ASSERT_EQ(18U, order.Size()); | |
1371 int task_index = 0; | |
1372 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
1373 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, true)); | |
1374 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, true)); | |
1375 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, true)); | |
1376 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, true)); | |
1377 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, false)); | |
1378 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 6, true)); | |
1379 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 6, false)); | |
1380 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 7, true)); | |
1381 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 7, false)); | |
1382 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 8, true)); | |
1383 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 8, false)); | |
1384 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 9, true)); | |
1385 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 9, false)); | |
1386 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, false)); | |
1387 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, false)); | |
1388 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, false)); | |
1389 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
1390 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
1391 } | |
1392 | |
1393 void PostNTasksThenQuit(int posts_remaining) { | 548 void PostNTasksThenQuit(int posts_remaining) { |
1394 if (posts_remaining > 1) { | 549 if (posts_remaining > 1) { |
1395 MessageLoop::current()->PostTask( | 550 MessageLoop::current()->PostTask( |
1396 FROM_HERE, | 551 FROM_HERE, |
1397 Bind(&PostNTasksThenQuit, posts_remaining - 1)); | 552 Bind(&PostNTasksThenQuit, posts_remaining - 1)); |
1398 } else { | 553 } else { |
1399 MessageLoop::current()->QuitWhenIdle(); | 554 MessageLoop::current()->QuitWhenIdle(); |
1400 } | 555 } |
1401 } | 556 } |
1402 | 557 |
1403 void RunTest_RecursivePosts(MessageLoop::Type message_loop_type, | |
1404 int num_times) { | |
1405 MessageLoop loop(message_loop_type); | |
1406 loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, num_times)); | |
1407 loop.Run(); | |
1408 } | |
1409 | |
1410 #if defined(OS_WIN) | 558 #if defined(OS_WIN) |
1411 | 559 |
1412 class DispatcherImpl : public MessageLoopForUI::Dispatcher { | 560 class DispatcherImpl : public MessageLoopForUI::Dispatcher { |
1413 public: | 561 public: |
1414 DispatcherImpl() : dispatch_count_(0) {} | 562 DispatcherImpl() : dispatch_count_(0) {} |
1415 | 563 |
1416 virtual bool Dispatch(const NativeEvent& msg) OVERRIDE { | 564 virtual bool Dispatch(const NativeEvent& msg) OVERRIDE { |
1417 ::TranslateMessage(&msg); | 565 ::TranslateMessage(&msg); |
1418 ::DispatchMessage(&msg); | 566 ::DispatchMessage(&msg); |
1419 // Do not count WM_TIMER since it is not what we post and it will cause | 567 // Do not count WM_TIMER since it is not what we post and it will cause |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1615 | 763 |
1616 #endif // defined(OS_WIN) | 764 #endif // defined(OS_WIN) |
1617 | 765 |
1618 } // namespace | 766 } // namespace |
1619 | 767 |
1620 //----------------------------------------------------------------------------- | 768 //----------------------------------------------------------------------------- |
1621 // Each test is run against each type of MessageLoop. That way we are sure | 769 // Each test is run against each type of MessageLoop. That way we are sure |
1622 // that message loops work properly in all configurations. Of course, in some | 770 // that message loops work properly in all configurations. Of course, in some |
1623 // cases, a unit test may only be for a particular type of loop. | 771 // cases, a unit test may only be for a particular type of loop. |
1624 | 772 |
1625 TEST(MessageLoopTest, PostTask) { | 773 RUN_MESSAGE_LOOP_TESTS(Default, &TypeDefaultMessagePumpFactory); |
1626 RunTest_PostTask(MessageLoop::TYPE_DEFAULT); | 774 RUN_MESSAGE_LOOP_TESTS(UI, &TypeUIMessagePumpFactory); |
1627 RunTest_PostTask(MessageLoop::TYPE_UI); | 775 RUN_MESSAGE_LOOP_TESTS(IO, &TypeIOMessagePumpFactory); |
1628 RunTest_PostTask(MessageLoop::TYPE_IO); | |
1629 } | |
1630 | |
1631 TEST(MessageLoopTest, PostTask_SEH) { | |
1632 RunTest_PostTask_SEH(MessageLoop::TYPE_DEFAULT); | |
1633 RunTest_PostTask_SEH(MessageLoop::TYPE_UI); | |
1634 RunTest_PostTask_SEH(MessageLoop::TYPE_IO); | |
1635 } | |
1636 | |
1637 TEST(MessageLoopTest, PostDelayedTask_Basic) { | |
1638 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_DEFAULT); | |
1639 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_UI); | |
1640 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_IO); | |
1641 } | |
1642 | |
1643 TEST(MessageLoopTest, PostDelayedTask_InDelayOrder) { | |
1644 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_DEFAULT); | |
1645 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_UI); | |
1646 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_IO); | |
1647 } | |
1648 | |
1649 TEST(MessageLoopTest, PostDelayedTask_InPostOrder) { | |
1650 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_DEFAULT); | |
1651 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_UI); | |
1652 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_IO); | |
1653 } | |
1654 | |
1655 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_2) { | |
1656 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_DEFAULT); | |
1657 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_UI); | |
1658 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_IO); | |
1659 } | |
1660 | |
1661 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_3) { | |
1662 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_DEFAULT); | |
1663 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_UI); | |
1664 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_IO); | |
1665 } | |
1666 | |
1667 TEST(MessageLoopTest, PostDelayedTask_SharedTimer) { | |
1668 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_DEFAULT); | |
1669 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_UI); | |
1670 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_IO); | |
1671 } | |
1672 | 776 |
1673 #if defined(OS_WIN) | 777 #if defined(OS_WIN) |
1674 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) { | 778 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) { |
1675 RunTest_PostDelayedTask_SharedTimer_SubPump(); | 779 RunTest_PostDelayedTask_SharedTimer_SubPump(); |
1676 } | 780 } |
1677 #endif | |
1678 | 781 |
1679 // TODO(darin): MessageLoop does not support deleting all tasks in the | |
1680 // destructor. | |
1681 // Fails, http://crbug.com/50272. | |
1682 TEST(MessageLoopTest, DISABLED_EnsureDeletion) { | |
1683 RunTest_EnsureDeletion(MessageLoop::TYPE_DEFAULT); | |
1684 RunTest_EnsureDeletion(MessageLoop::TYPE_UI); | |
1685 RunTest_EnsureDeletion(MessageLoop::TYPE_IO); | |
1686 } | |
1687 | |
1688 // TODO(darin): MessageLoop does not support deleting all tasks in the | |
1689 // destructor. | |
1690 // Fails, http://crbug.com/50272. | |
1691 TEST(MessageLoopTest, DISABLED_EnsureDeletion_Chain) { | |
1692 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_DEFAULT); | |
1693 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_UI); | |
1694 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_IO); | |
1695 } | |
1696 | |
1697 #if defined(OS_WIN) | |
1698 TEST(MessageLoopTest, Crasher) { | 782 TEST(MessageLoopTest, Crasher) { |
1699 RunTest_Crasher(MessageLoop::TYPE_DEFAULT); | 783 RunTest_Crasher(MessageLoop::TYPE_DEFAULT); |
1700 RunTest_Crasher(MessageLoop::TYPE_UI); | 784 RunTest_Crasher(MessageLoop::TYPE_UI); |
1701 RunTest_Crasher(MessageLoop::TYPE_IO); | 785 RunTest_Crasher(MessageLoop::TYPE_IO); |
1702 } | 786 } |
1703 | 787 |
1704 TEST(MessageLoopTest, CrasherNasty) { | 788 TEST(MessageLoopTest, CrasherNasty) { |
1705 RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT); | 789 RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT); |
1706 RunTest_CrasherNasty(MessageLoop::TYPE_UI); | 790 RunTest_CrasherNasty(MessageLoop::TYPE_UI); |
1707 RunTest_CrasherNasty(MessageLoop::TYPE_IO); | 791 RunTest_CrasherNasty(MessageLoop::TYPE_IO); |
1708 } | 792 } |
1709 #endif // defined(OS_WIN) | |
1710 | 793 |
1711 TEST(MessageLoopTest, Nesting) { | |
1712 RunTest_Nesting(MessageLoop::TYPE_DEFAULT); | |
1713 RunTest_Nesting(MessageLoop::TYPE_UI); | |
1714 RunTest_Nesting(MessageLoop::TYPE_IO); | |
1715 } | |
1716 | |
1717 TEST(MessageLoopTest, RecursiveDenial1) { | |
1718 RunTest_RecursiveDenial1(MessageLoop::TYPE_DEFAULT); | |
1719 RunTest_RecursiveDenial1(MessageLoop::TYPE_UI); | |
1720 RunTest_RecursiveDenial1(MessageLoop::TYPE_IO); | |
1721 } | |
1722 | |
1723 TEST(MessageLoopTest, RecursiveDenial3) { | |
1724 RunTest_RecursiveDenial3(MessageLoop::TYPE_DEFAULT); | |
1725 RunTest_RecursiveDenial3(MessageLoop::TYPE_UI); | |
1726 RunTest_RecursiveDenial3(MessageLoop::TYPE_IO); | |
1727 } | |
1728 | |
1729 TEST(MessageLoopTest, RecursiveSupport1) { | |
1730 RunTest_RecursiveSupport1(MessageLoop::TYPE_DEFAULT); | |
1731 RunTest_RecursiveSupport1(MessageLoop::TYPE_UI); | |
1732 RunTest_RecursiveSupport1(MessageLoop::TYPE_IO); | |
1733 } | |
1734 | |
1735 #if defined(OS_WIN) | |
1736 // This test occasionally hangs http://crbug.com/44567 | 794 // This test occasionally hangs http://crbug.com/44567 |
1737 TEST(MessageLoopTest, DISABLED_RecursiveDenial2) { | 795 TEST(MessageLoopTest, DISABLED_RecursiveDenial2) { |
1738 RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT); | 796 RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT); |
1739 RunTest_RecursiveDenial2(MessageLoop::TYPE_UI); | 797 RunTest_RecursiveDenial2(MessageLoop::TYPE_UI); |
1740 RunTest_RecursiveDenial2(MessageLoop::TYPE_IO); | 798 RunTest_RecursiveDenial2(MessageLoop::TYPE_IO); |
1741 } | 799 } |
1742 | 800 |
1743 TEST(MessageLoopTest, RecursiveSupport2) { | 801 TEST(MessageLoopTest, RecursiveSupport2) { |
1744 // This test requires a UI loop | 802 // This test requires a UI loop |
1745 RunTest_RecursiveSupport2(MessageLoop::TYPE_UI); | 803 RunTest_RecursiveSupport2(MessageLoop::TYPE_UI); |
1746 } | 804 } |
1747 #endif // defined(OS_WIN) | 805 #endif // defined(OS_WIN) |
1748 | 806 |
1749 TEST(MessageLoopTest, NonNestableWithNoNesting) { | |
1750 RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_DEFAULT); | |
1751 RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_UI); | |
1752 RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_IO); | |
1753 } | |
1754 | |
1755 TEST(MessageLoopTest, NonNestableInNestedLoop) { | |
1756 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, false); | |
1757 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, false); | |
1758 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, false); | |
1759 } | |
1760 | |
1761 TEST(MessageLoopTest, NonNestableDelayedInNestedLoop) { | |
1762 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, true); | |
1763 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, true); | |
1764 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, true); | |
1765 } | |
1766 | |
1767 TEST(MessageLoopTest, QuitNow) { | |
1768 RunTest_QuitNow(MessageLoop::TYPE_DEFAULT); | |
1769 RunTest_QuitNow(MessageLoop::TYPE_UI); | |
1770 RunTest_QuitNow(MessageLoop::TYPE_IO); | |
1771 } | |
1772 | |
1773 TEST(MessageLoopTest, RunLoopQuitTop) { | |
1774 RunTest_RunLoopQuitTop(MessageLoop::TYPE_DEFAULT); | |
1775 RunTest_RunLoopQuitTop(MessageLoop::TYPE_UI); | |
1776 RunTest_RunLoopQuitTop(MessageLoop::TYPE_IO); | |
1777 } | |
1778 | |
1779 TEST(MessageLoopTest, RunLoopQuitNested) { | |
1780 RunTest_RunLoopQuitNested(MessageLoop::TYPE_DEFAULT); | |
1781 RunTest_RunLoopQuitNested(MessageLoop::TYPE_UI); | |
1782 RunTest_RunLoopQuitNested(MessageLoop::TYPE_IO); | |
1783 } | |
1784 | |
1785 TEST(MessageLoopTest, RunLoopQuitBogus) { | |
1786 RunTest_RunLoopQuitBogus(MessageLoop::TYPE_DEFAULT); | |
1787 RunTest_RunLoopQuitBogus(MessageLoop::TYPE_UI); | |
1788 RunTest_RunLoopQuitBogus(MessageLoop::TYPE_IO); | |
1789 } | |
1790 | |
1791 TEST(MessageLoopTest, RunLoopQuitDeep) { | |
1792 RunTest_RunLoopQuitDeep(MessageLoop::TYPE_DEFAULT); | |
1793 RunTest_RunLoopQuitDeep(MessageLoop::TYPE_UI); | |
1794 RunTest_RunLoopQuitDeep(MessageLoop::TYPE_IO); | |
1795 } | |
1796 | |
1797 TEST(MessageLoopTest, RunLoopQuitOrderBefore) { | |
1798 RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_DEFAULT); | |
1799 RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_UI); | |
1800 RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_IO); | |
1801 } | |
1802 | |
1803 TEST(MessageLoopTest, RunLoopQuitOrderDuring) { | |
1804 RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_DEFAULT); | |
1805 RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_UI); | |
1806 RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_IO); | |
1807 } | |
1808 | |
1809 TEST(MessageLoopTest, RunLoopQuitOrderAfter) { | |
1810 RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_DEFAULT); | |
1811 RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_UI); | |
1812 RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_IO); | |
1813 } | |
1814 | |
1815 class DummyTaskObserver : public MessageLoop::TaskObserver { | 807 class DummyTaskObserver : public MessageLoop::TaskObserver { |
1816 public: | 808 public: |
1817 explicit DummyTaskObserver(int num_tasks) | 809 explicit DummyTaskObserver(int num_tasks) |
1818 : num_tasks_started_(0), | 810 : num_tasks_started_(0), |
1819 num_tasks_processed_(0), | 811 num_tasks_processed_(0), |
1820 num_tasks_(num_tasks) {} | 812 num_tasks_(num_tasks) {} |
1821 | 813 |
1822 virtual ~DummyTaskObserver() {} | 814 virtual ~DummyTaskObserver() {} |
1823 | 815 |
1824 virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE { | 816 virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE { |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2081 EXPECT_EQ(foo->result(), "a"); | 1073 EXPECT_EQ(foo->result(), "a"); |
2082 } | 1074 } |
2083 | 1075 |
2084 TEST(MessageLoopTest, IsType) { | 1076 TEST(MessageLoopTest, IsType) { |
2085 MessageLoop loop(MessageLoop::TYPE_UI); | 1077 MessageLoop loop(MessageLoop::TYPE_UI); |
2086 EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); | 1078 EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); |
2087 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); | 1079 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); |
2088 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); | 1080 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); |
2089 } | 1081 } |
2090 | 1082 |
2091 TEST(MessageLoopTest, RecursivePosts) { | |
2092 // There was a bug in the MessagePumpGLib where posting tasks recursively | |
2093 // caused the message loop to hang, due to the buffer of the internal pipe | |
2094 // becoming full. Test all MessageLoop types to ensure this issue does not | |
2095 // exist in other MessagePumps. | |
2096 | |
2097 // On Linux, the pipe buffer size is 64KiB by default. The bug caused one | |
2098 // byte accumulated in the pipe per two posts, so we should repeat 128K | |
2099 // times to reproduce the bug. | |
2100 const int kNumTimes = 1 << 17; | |
2101 RunTest_RecursivePosts(MessageLoop::TYPE_DEFAULT, kNumTimes); | |
2102 RunTest_RecursivePosts(MessageLoop::TYPE_UI, kNumTimes); | |
2103 RunTest_RecursivePosts(MessageLoop::TYPE_IO, kNumTimes); | |
2104 } | |
2105 | |
2106 } // namespace base | 1083 } // namespace base |
OLD | NEW |