Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(707)

Side by Side Diff: base/message_loop/message_loop_unittest.cc

Issue 66193007: Implementation of MessagePump for Mojo. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge 2 trunk Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/message_loop/message_loop_test.cc ('k') | mojo/common/message_pump_mojo.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « base/message_loop/message_loop_test.cc ('k') | mojo/common/message_pump_mojo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698