- add sources.
[platform/framework/web/crosswalk.git] / src / base / message_loop / message_loop_unittest.cc
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
3 // found in the LICENSE file.
4
5 #include <vector>
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/message_loop/message_loop_proxy_impl.h"
14 #include "base/pending_task.h"
15 #include "base/posix/eintr_wrapper.h"
16 #include "base/run_loop.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "base/thread_task_runner_handle.h"
19 #include "base/threading/platform_thread.h"
20 #include "base/threading/thread.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 #if defined(OS_WIN)
24 #include "base/message_loop/message_pump_win.h"
25 #include "base/win/scoped_handle.h"
26 #endif
27
28 namespace base {
29
30 // TODO(darin): Platform-specific MessageLoop tests should be grouped together
31 // to avoid chopping this file up with so many #ifdefs.
32
33 namespace {
34
35 class Foo : public RefCounted<Foo> {
36  public:
37   Foo() : test_count_(0) {
38   }
39
40   void Test0() {
41     ++test_count_;
42   }
43
44   void Test1ConstRef(const std::string& a) {
45     ++test_count_;
46     result_.append(a);
47   }
48
49   void Test1Ptr(std::string* a) {
50     ++test_count_;
51     result_.append(*a);
52   }
53
54   void Test1Int(int a) {
55     test_count_ += a;
56   }
57
58   void Test2Ptr(std::string* a, std::string* b) {
59     ++test_count_;
60     result_.append(*a);
61     result_.append(*b);
62   }
63
64   void Test2Mixed(const std::string& a, std::string* b) {
65     ++test_count_;
66     result_.append(a);
67     result_.append(*b);
68   }
69
70   int test_count() const { return test_count_; }
71   const std::string& result() const { return result_; }
72
73  private:
74   friend class RefCounted<Foo>;
75
76   ~Foo() {}
77
78   int test_count_;
79   std::string result_;
80 };
81
82 void RunTest_PostTask(MessageLoop::Type message_loop_type) {
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
165 // This function runs slowly to simulate a large amount of work being done.
166 static void SlowFunc(TimeDelta pause, int* quit_counter) {
167     PlatformThread::Sleep(pause);
168     if (--(*quit_counter) == 0)
169       MessageLoop::current()->QuitWhenIdle();
170 }
171
172 // This function records the time when Run was called in a Time object, which is
173 // useful for building a variety of MessageLoop tests.
174 static void RecordRunTimeFunc(Time* run_time, int* quit_counter) {
175   *run_time = Time::Now();
176
177     // 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,
179     // without worry about the resolution of our system clock being an issue.
180   SlowFunc(TimeDelta::FromMilliseconds(10), quit_counter);
181 }
182
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() {
358   MessageLoop::current()->SetNestableTasksAllowed(true);
359   MSG msg;
360   while (GetMessage(&msg, NULL, 0, 0)) {
361     TranslateMessage(&msg);
362     DispatchMessage(&msg);
363   }
364   MessageLoop::current()->QuitWhenIdle();
365 }
366
367 void RunTest_PostDelayedTask_SharedTimer_SubPump() {
368   MessageLoop loop(MessageLoop::TYPE_UI);
369
370   // Test that the interval of the timer, used to run the next delayed task, is
371   // set to a value corresponding to when the next delayed task should run.
372
373   // By setting num_tasks to 1, we ensure that the first task to run causes the
374   // run loop to exit.
375   int num_tasks = 1;
376   Time run_time;
377
378   loop.PostTask(FROM_HERE, Bind(&SubPumpFunc));
379
380   // This very delayed task should never run.
381   loop.PostDelayedTask(
382       FROM_HERE,
383       Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
384       TimeDelta::FromSeconds(1000));
385
386   // This slightly delayed task should run from within SubPumpFunc).
387   loop.PostDelayedTask(
388       FROM_HERE,
389       Bind(&PostQuitMessage, 0),
390       TimeDelta::FromMilliseconds(10));
391
392   Time start_time = Time::Now();
393
394   loop.Run();
395   EXPECT_EQ(1, num_tasks);
396
397   // Ensure that we ran in far less time than the slower timer.
398   TimeDelta total_time = Time::Now() - start_time;
399   EXPECT_GT(5000, total_time.InMilliseconds());
400
401   // 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
403   // encouraging flakiness if there is any.
404   PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
405   RunLoop().RunUntilIdle();
406
407   EXPECT_TRUE(run_time.is_null());
408 }
409
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) {
487   ADD_FAILURE() << "bad exception handler";
488   ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode);
489   return EXCEPTION_EXECUTE_HANDLER;
490 }
491
492 // 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.
494 class Crasher : public RefCounted<Crasher> {
495  public:
496   // Ctor. If trash_SEH_handler is true, the task will override the unhandled
497   // exception handler with one sure to crash this test.
498   explicit Crasher(bool trash_SEH_handler)
499       : trash_SEH_handler_(trash_SEH_handler) {
500   }
501
502   void Run() {
503     PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
504     if (trash_SEH_handler_)
505       ::SetUnhandledExceptionFilter(&BadExceptionHandler);
506     // Generate a SEH fault. We do it in asm to make sure we know how to undo
507     // the damage.
508
509 #if defined(_M_IX86)
510
511     __asm {
512       mov eax, dword ptr [Crasher::bad_array_]
513       mov byte ptr [eax], 66
514     }
515
516 #elif defined(_M_X64)
517
518     bad_array_[0] = 66;
519
520 #else
521 #error "needs architecture support"
522 #endif
523
524     MessageLoop::current()->QuitWhenIdle();
525   }
526   // Points the bad array to a valid memory location.
527   static void FixError() {
528     bad_array_ = &valid_store_;
529   }
530
531  private:
532   bool trash_SEH_handler_;
533   static volatile char* bad_array_;
534   static char valid_store_;
535 };
536
537 volatile char* Crasher::bad_array_ = 0;
538 char Crasher::valid_store_ = 0;
539
540 // This SEH filter fixes the problem and retries execution. Fixing requires
541 // that the last instruction: mov eax, [Crasher::bad_array_] to be retried
542 // so we move the instruction pointer 5 bytes back.
543 LONG WINAPI HandleCrasherException(EXCEPTION_POINTERS *ex_info) {
544   if (ex_info->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
545     return EXCEPTION_EXECUTE_HANDLER;
546
547   Crasher::FixError();
548
549 #if defined(_M_IX86)
550
551   ex_info->ContextRecord->Eip -= 5;
552
553 #elif defined(_M_X64)
554
555   ex_info->ContextRecord->Rip -= 5;
556
557 #endif
558
559   return EXCEPTION_CONTINUE_EXECUTION;
560 }
561
562 void RunTest_Crasher(MessageLoop::Type message_loop_type) {
563   MessageLoop loop(message_loop_type);
564
565   if (::IsDebuggerPresent())
566     return;
567
568   LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter =
569       ::SetUnhandledExceptionFilter(&HandleCrasherException);
570
571   MessageLoop::current()->PostTask(
572       FROM_HERE,
573       Bind(&Crasher::Run, new Crasher(false)));
574   MessageLoop::current()->set_exception_restoration(true);
575   MessageLoop::current()->Run();
576   MessageLoop::current()->set_exception_restoration(false);
577
578   ::SetUnhandledExceptionFilter(old_SEH_filter);
579 }
580
581 void RunTest_CrasherNasty(MessageLoop::Type message_loop_type) {
582   MessageLoop loop(message_loop_type);
583
584   if (::IsDebuggerPresent())
585     return;
586
587   LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter =
588       ::SetUnhandledExceptionFilter(&HandleCrasherException);
589
590   MessageLoop::current()->PostTask(
591       FROM_HERE,
592       Bind(&Crasher::Run, new Crasher(true)));
593   MessageLoop::current()->set_exception_restoration(true);
594   MessageLoop::current()->Run();
595   MessageLoop::current()->set_exception_restoration(false);
596
597   ::SetUnhandledExceptionFilter(old_SEH_filter);
598 }
599
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";
614 #endif  // defined(OS_WIN)
615
616 enum TaskType {
617   MESSAGEBOX,
618   ENDDIALOG,
619   RECURSIVE,
620   TIMEDMESSAGELOOP,
621   QUITMESSAGELOOP,
622   ORDERED,
623   PUMPS,
624   SLEEP,
625   RUNS,
626 };
627
628 // Saves the order in which the tasks executed.
629 struct TaskItem {
630   TaskItem(TaskType t, int c, bool s)
631       : type(t),
632         cookie(c),
633         start(s) {
634   }
635
636   TaskType type;
637   int cookie;
638   bool start;
639
640   bool operator == (const TaskItem& other) const {
641     return type == other.type && cookie == other.cookie && start == other.start;
642   }
643 };
644
645 std::ostream& operator <<(std::ostream& os, TaskType type) {
646   switch (type) {
647   case MESSAGEBOX:        os << "MESSAGEBOX"; break;
648   case ENDDIALOG:         os << "ENDDIALOG"; break;
649   case RECURSIVE:         os << "RECURSIVE"; break;
650   case TIMEDMESSAGELOOP:  os << "TIMEDMESSAGELOOP"; break;
651   case QUITMESSAGELOOP:   os << "QUITMESSAGELOOP"; break;
652   case ORDERED:          os << "ORDERED"; break;
653   case PUMPS:             os << "PUMPS"; break;
654   case SLEEP:             os << "SLEEP"; break;
655   default:
656     NOTREACHED();
657     os << "Unknown TaskType";
658     break;
659   }
660   return os;
661 }
662
663 std::ostream& operator <<(std::ostream& os, const TaskItem& item) {
664   if (item.start)
665     return os << item.type << " " << item.cookie << " starts";
666   else
667     return os << item.type << " " << item.cookie << " ends";
668 }
669
670 class TaskList {
671  public:
672   void RecordStart(TaskType type, int cookie) {
673     TaskItem item(type, cookie, true);
674     DVLOG(1) << item;
675     task_list_.push_back(item);
676   }
677
678   void RecordEnd(TaskType type, int cookie) {
679     TaskItem item(type, cookie, false);
680     DVLOG(1) << item;
681     task_list_.push_back(item);
682   }
683
684   size_t Size() {
685     return task_list_.size();
686   }
687
688   TaskItem Get(int n)  {
689     return task_list_[n];
690   }
691
692  private:
693   std::vector<TaskItem> task_list_;
694 };
695
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,
705 // common controls (like OpenFile) and StartDoc printing function can cause
706 // implicit message loops.
707 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) {
708   order->RecordStart(MESSAGEBOX, cookie);
709   if (is_reentrant)
710     MessageLoop::current()->SetNestableTasksAllowed(true);
711   MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK);
712   order->RecordEnd(MESSAGEBOX, cookie);
713 }
714
715 // Will end the MessageBox.
716 void EndDialogFunc(TaskList* order, int cookie) {
717   order->RecordStart(ENDDIALOG, cookie);
718   HWND window = GetActiveWindow();
719   if (window != NULL) {
720     EXPECT_NE(EndDialog(window, IDCONTINUE), 0);
721     // Cheap way to signal that the window wasn't found if RunEnd() isn't
722     // called.
723     order->RecordEnd(ENDDIALOG, cookie);
724   }
725 }
726
727 #endif  // defined(OS_WIN)
728
729 void RecursiveFunc(TaskList* order, int cookie, int depth,
730                    bool is_reentrant) {
731   order->RecordStart(RECURSIVE, cookie);
732   if (depth > 0) {
733     if (is_reentrant)
734       MessageLoop::current()->SetNestableTasksAllowed(true);
735     MessageLoop::current()->PostTask(
736         FROM_HERE,
737         Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant));
738   }
739   order->RecordEnd(RECURSIVE, cookie);
740 }
741
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) {
749   order->RecordStart(QUITMESSAGELOOP, cookie);
750   MessageLoop::current()->QuitWhenIdle();
751   order->RecordEnd(QUITMESSAGELOOP, cookie);
752 }
753
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,
762                       HANDLE event,
763                       bool expect_window,
764                       TaskList* order,
765                       bool is_reentrant) {
766   target->PostTask(FROM_HERE,
767                    Bind(&RecursiveFunc, order, 1, 2, is_reentrant));
768   target->PostTask(FROM_HERE,
769                    Bind(&MessageBoxFunc, order, 2, is_reentrant));
770   target->PostTask(FROM_HERE,
771                    Bind(&RecursiveFunc, order, 3, 2, is_reentrant));
772   // The trick here is that for recursive task processing, this task will be
773   // ran _inside_ the MessageBox message loop, dismissing the MessageBox
774   // without a chance.
775   // For non-recursive task processing, this will be executed _after_ the
776   // MessageBox will have been dismissed by the code below, where
777   // expect_window_ is true.
778   target->PostTask(FROM_HERE,
779                    Bind(&EndDialogFunc, order, 4));
780   target->PostTask(FROM_HERE,
781                    Bind(&QuitFunc, order, 5));
782
783   // Enforce that every tasks are sent before starting to run the main thread
784   // message loop.
785   ASSERT_TRUE(SetEvent(event));
786
787   // Poll for the MessageBox. Don't do this at home! At the speed we do it,
788   // you will never realize one MessageBox was shown.
789   for (; expect_window;) {
790     HWND window = FindWindow(L"#32770", kMessageBoxTitle);
791     if (window) {
792       // Dismiss it.
793       for (;;) {
794         HWND button = FindWindowEx(window, NULL, L"Button", NULL);
795         if (button != NULL) {
796           EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0));
797           EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0));
798           break;
799         }
800       }
801       break;
802     }
803   }
804 }
805
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
916 // message loop functionality.
917
918 // A side effect of this test is the generation a beep. Sorry.
919 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) {
920   MessageLoop loop(message_loop_type);
921
922   Thread worker("RecursiveDenial2_worker");
923   Thread::Options options;
924   options.message_loop_type = message_loop_type;
925   ASSERT_EQ(true, worker.StartWithOptions(options));
926   TaskList order;
927   win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
928   worker.message_loop()->PostTask(FROM_HERE,
929                                   Bind(&RecursiveFuncWin,
930                                              MessageLoop::current(),
931                                              event.Get(),
932                                              true,
933                                              &order,
934                                              false));
935   // Let the other thread execute.
936   WaitForSingleObject(event, INFINITE);
937   MessageLoop::current()->Run();
938
939   ASSERT_EQ(order.Size(), 17);
940   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
941   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
942   EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true));
943   EXPECT_EQ(order.Get(3), TaskItem(MESSAGEBOX, 2, false));
944   EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, true));
945   EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 3, false));
946   // When EndDialogFunc is processed, the window is already dismissed, hence no
947   // "end" entry.
948   EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, true));
949   EXPECT_EQ(order.Get(7), TaskItem(QUITMESSAGELOOP, 5, true));
950   EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, false));
951   EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 1, true));
952   EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, false));
953   EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 3, true));
954   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, false));
955   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, true));
956   EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, false));
957   EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 3, true));
958   EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, false));
959 }
960
961 // A side effect of this test is the generation a beep. Sorry.  This test also
962 // needs to process windows messages on the current thread.
963 void RunTest_RecursiveSupport2(MessageLoop::Type message_loop_type) {
964   MessageLoop loop(message_loop_type);
965
966   Thread worker("RecursiveSupport2_worker");
967   Thread::Options options;
968   options.message_loop_type = message_loop_type;
969   ASSERT_EQ(true, worker.StartWithOptions(options));
970   TaskList order;
971   win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
972   worker.message_loop()->PostTask(FROM_HERE,
973                                   Bind(&RecursiveFuncWin,
974                                              MessageLoop::current(),
975                                              event.Get(),
976                                              false,
977                                              &order,
978                                              true));
979   // Let the other thread execute.
980   WaitForSingleObject(event, INFINITE);
981   MessageLoop::current()->Run();
982
983   ASSERT_EQ(order.Size(), 18);
984   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
985   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
986   EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true));
987   // Note that this executes in the MessageBox modal loop.
988   EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 3, true));
989   EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, false));
990   EXPECT_EQ(order.Get(5), TaskItem(ENDDIALOG, 4, true));
991   EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, false));
992   EXPECT_EQ(order.Get(7), TaskItem(MESSAGEBOX, 2, false));
993   /* The order can subtly change here. The reason is that when RecursiveFunc(1)
994      is called in the main thread, if it is faster than getting to the
995      PostTask(FROM_HERE, Bind(&QuitFunc) execution, the order of task
996      execution can change. We don't care anyway that the order isn't correct.
997   EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, true));
998   EXPECT_EQ(order.Get(9), TaskItem(QUITMESSAGELOOP, 5, false));
999   EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
1000   EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
1001   */
1002   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true));
1003   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false));
1004   EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true));
1005   EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false));
1006   EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true));
1007   EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false));
1008 }
1009
1010 #endif  // defined(OS_WIN)
1011
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) {
1394   if (posts_remaining > 1) {
1395     MessageLoop::current()->PostTask(
1396         FROM_HERE,
1397         Bind(&PostNTasksThenQuit, posts_remaining - 1));
1398   } else {
1399     MessageLoop::current()->QuitWhenIdle();
1400   }
1401 }
1402
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)
1411
1412 class DispatcherImpl : public MessageLoopForUI::Dispatcher {
1413  public:
1414   DispatcherImpl() : dispatch_count_(0) {}
1415
1416   virtual bool Dispatch(const NativeEvent& msg) OVERRIDE {
1417     ::TranslateMessage(&msg);
1418     ::DispatchMessage(&msg);
1419     // Do not count WM_TIMER since it is not what we post and it will cause
1420     // flakiness.
1421     if (msg.message != WM_TIMER)
1422       ++dispatch_count_;
1423     // We treat WM_LBUTTONUP as the last message.
1424     return msg.message != WM_LBUTTONUP;
1425   }
1426
1427   int dispatch_count_;
1428 };
1429
1430 void MouseDownUp() {
1431   PostMessage(NULL, WM_LBUTTONDOWN, 0, 0);
1432   PostMessage(NULL, WM_LBUTTONUP, 'A', 0);
1433 }
1434
1435 void RunTest_Dispatcher(MessageLoop::Type message_loop_type) {
1436   MessageLoop loop(message_loop_type);
1437
1438   MessageLoop::current()->PostDelayedTask(
1439       FROM_HERE,
1440       Bind(&MouseDownUp),
1441       TimeDelta::FromMilliseconds(100));
1442   DispatcherImpl dispatcher;
1443   RunLoop run_loop(&dispatcher);
1444   run_loop.Run();
1445   ASSERT_EQ(2, dispatcher.dispatch_count_);
1446 }
1447
1448 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) {
1449   if (code == MessagePumpForUI::kMessageFilterCode) {
1450     MSG* msg = reinterpret_cast<MSG*>(lparam);
1451     if (msg->message == WM_LBUTTONDOWN)
1452       return TRUE;
1453   }
1454   return FALSE;
1455 }
1456
1457 void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) {
1458   MessageLoop loop(message_loop_type);
1459
1460   MessageLoop::current()->PostDelayedTask(
1461       FROM_HERE,
1462       Bind(&MouseDownUp),
1463       TimeDelta::FromMilliseconds(100));
1464   HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER,
1465                                     MsgFilterProc,
1466                                     NULL,
1467                                     GetCurrentThreadId());
1468   DispatcherImpl dispatcher;
1469   RunLoop run_loop(&dispatcher);
1470   run_loop.Run();
1471   ASSERT_EQ(1, dispatcher.dispatch_count_);
1472   UnhookWindowsHookEx(msg_hook);
1473 }
1474
1475 class TestIOHandler : public MessageLoopForIO::IOHandler {
1476  public:
1477   TestIOHandler(const wchar_t* name, HANDLE signal, bool wait);
1478
1479   virtual void OnIOCompleted(MessageLoopForIO::IOContext* context,
1480                              DWORD bytes_transfered, DWORD error);
1481
1482   void Init();
1483   void WaitForIO();
1484   OVERLAPPED* context() { return &context_.overlapped; }
1485   DWORD size() { return sizeof(buffer_); }
1486
1487  private:
1488   char buffer_[48];
1489   MessageLoopForIO::IOContext context_;
1490   HANDLE signal_;
1491   win::ScopedHandle file_;
1492   bool wait_;
1493 };
1494
1495 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait)
1496     : signal_(signal), wait_(wait) {
1497   memset(buffer_, 0, sizeof(buffer_));
1498   memset(&context_, 0, sizeof(context_));
1499   context_.handler = this;
1500
1501   file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
1502                        FILE_FLAG_OVERLAPPED, NULL));
1503   EXPECT_TRUE(file_.IsValid());
1504 }
1505
1506 void TestIOHandler::Init() {
1507   MessageLoopForIO::current()->RegisterIOHandler(file_, this);
1508
1509   DWORD read;
1510   EXPECT_FALSE(ReadFile(file_, buffer_, size(), &read, context()));
1511   EXPECT_EQ(ERROR_IO_PENDING, GetLastError());
1512   if (wait_)
1513     WaitForIO();
1514 }
1515
1516 void TestIOHandler::OnIOCompleted(MessageLoopForIO::IOContext* context,
1517                                   DWORD bytes_transfered, DWORD error) {
1518   ASSERT_TRUE(context == &context_);
1519   ASSERT_TRUE(SetEvent(signal_));
1520 }
1521
1522 void TestIOHandler::WaitForIO() {
1523   EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this));
1524   EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this));
1525 }
1526
1527 void RunTest_IOHandler() {
1528   win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL));
1529   ASSERT_TRUE(callback_called.IsValid());
1530
1531   const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe";
1532   win::ScopedHandle server(
1533       CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
1534   ASSERT_TRUE(server.IsValid());
1535
1536   Thread thread("IOHandler test");
1537   Thread::Options options;
1538   options.message_loop_type = MessageLoop::TYPE_IO;
1539   ASSERT_TRUE(thread.StartWithOptions(options));
1540
1541   MessageLoop* thread_loop = thread.message_loop();
1542   ASSERT_TRUE(NULL != thread_loop);
1543
1544   TestIOHandler handler(kPipeName, callback_called, false);
1545   thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
1546                                               Unretained(&handler)));
1547   // Make sure the thread runs and sleeps for lack of work.
1548   PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
1549
1550   const char buffer[] = "Hello there!";
1551   DWORD written;
1552   EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL));
1553
1554   DWORD result = WaitForSingleObject(callback_called, 1000);
1555   EXPECT_EQ(WAIT_OBJECT_0, result);
1556
1557   thread.Stop();
1558 }
1559
1560 void RunTest_WaitForIO() {
1561   win::ScopedHandle callback1_called(
1562       CreateEvent(NULL, TRUE, FALSE, NULL));
1563   win::ScopedHandle callback2_called(
1564       CreateEvent(NULL, TRUE, FALSE, NULL));
1565   ASSERT_TRUE(callback1_called.IsValid());
1566   ASSERT_TRUE(callback2_called.IsValid());
1567
1568   const wchar_t* kPipeName1 = L"\\\\.\\pipe\\iohandler_pipe1";
1569   const wchar_t* kPipeName2 = L"\\\\.\\pipe\\iohandler_pipe2";
1570   win::ScopedHandle server1(
1571       CreateNamedPipe(kPipeName1, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
1572   win::ScopedHandle server2(
1573       CreateNamedPipe(kPipeName2, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
1574   ASSERT_TRUE(server1.IsValid());
1575   ASSERT_TRUE(server2.IsValid());
1576
1577   Thread thread("IOHandler test");
1578   Thread::Options options;
1579   options.message_loop_type = MessageLoop::TYPE_IO;
1580   ASSERT_TRUE(thread.StartWithOptions(options));
1581
1582   MessageLoop* thread_loop = thread.message_loop();
1583   ASSERT_TRUE(NULL != thread_loop);
1584
1585   TestIOHandler handler1(kPipeName1, callback1_called, false);
1586   TestIOHandler handler2(kPipeName2, callback2_called, true);
1587   thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
1588                                               Unretained(&handler1)));
1589   // TODO(ajwong): Do we really need such long Sleeps in ths function?
1590   // Make sure the thread runs and sleeps for lack of work.
1591   TimeDelta delay = TimeDelta::FromMilliseconds(100);
1592   PlatformThread::Sleep(delay);
1593   thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
1594                                               Unretained(&handler2)));
1595   PlatformThread::Sleep(delay);
1596
1597   // At this time handler1 is waiting to be called, and the thread is waiting
1598   // on the Init method of handler2, filtering only handler2 callbacks.
1599
1600   const char buffer[] = "Hello there!";
1601   DWORD written;
1602   EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL));
1603   PlatformThread::Sleep(2 * delay);
1604   EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) <<
1605       "handler1 has not been called";
1606
1607   EXPECT_TRUE(WriteFile(server2, buffer, sizeof(buffer), &written, NULL));
1608
1609   HANDLE objects[2] = { callback1_called.Get(), callback2_called.Get() };
1610   DWORD result = WaitForMultipleObjects(2, objects, TRUE, 1000);
1611   EXPECT_EQ(WAIT_OBJECT_0, result);
1612
1613   thread.Stop();
1614 }
1615
1616 #endif  // defined(OS_WIN)
1617
1618 }  // namespace
1619
1620 //-----------------------------------------------------------------------------
1621 // 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
1623 // cases, a unit test may only be for a particular type of loop.
1624
1625 TEST(MessageLoopTest, PostTask) {
1626   RunTest_PostTask(MessageLoop::TYPE_DEFAULT);
1627   RunTest_PostTask(MessageLoop::TYPE_UI);
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
1673 #if defined(OS_WIN)
1674 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) {
1675   RunTest_PostDelayedTask_SharedTimer_SubPump();
1676 }
1677 #endif
1678
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) {
1699   RunTest_Crasher(MessageLoop::TYPE_DEFAULT);
1700   RunTest_Crasher(MessageLoop::TYPE_UI);
1701   RunTest_Crasher(MessageLoop::TYPE_IO);
1702 }
1703
1704 TEST(MessageLoopTest, CrasherNasty) {
1705   RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT);
1706   RunTest_CrasherNasty(MessageLoop::TYPE_UI);
1707   RunTest_CrasherNasty(MessageLoop::TYPE_IO);
1708 }
1709 #endif  // defined(OS_WIN)
1710
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
1737 TEST(MessageLoopTest, DISABLED_RecursiveDenial2) {
1738   RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT);
1739   RunTest_RecursiveDenial2(MessageLoop::TYPE_UI);
1740   RunTest_RecursiveDenial2(MessageLoop::TYPE_IO);
1741 }
1742
1743 TEST(MessageLoopTest, RecursiveSupport2) {
1744   // This test requires a UI loop
1745   RunTest_RecursiveSupport2(MessageLoop::TYPE_UI);
1746 }
1747 #endif  // defined(OS_WIN)
1748
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 {
1816  public:
1817   explicit DummyTaskObserver(int num_tasks)
1818       : num_tasks_started_(0),
1819         num_tasks_processed_(0),
1820         num_tasks_(num_tasks) {}
1821
1822   virtual ~DummyTaskObserver() {}
1823
1824   virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE {
1825     num_tasks_started_++;
1826     EXPECT_TRUE(pending_task.time_posted != TimeTicks());
1827     EXPECT_LE(num_tasks_started_, num_tasks_);
1828     EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1);
1829   }
1830
1831   virtual void DidProcessTask(const PendingTask& pending_task) OVERRIDE {
1832     num_tasks_processed_++;
1833     EXPECT_TRUE(pending_task.time_posted != TimeTicks());
1834     EXPECT_LE(num_tasks_started_, num_tasks_);
1835     EXPECT_EQ(num_tasks_started_, num_tasks_processed_);
1836   }
1837
1838   int num_tasks_started() const { return num_tasks_started_; }
1839   int num_tasks_processed() const { return num_tasks_processed_; }
1840
1841  private:
1842   int num_tasks_started_;
1843   int num_tasks_processed_;
1844   const int num_tasks_;
1845
1846   DISALLOW_COPY_AND_ASSIGN(DummyTaskObserver);
1847 };
1848
1849 TEST(MessageLoopTest, TaskObserver) {
1850   const int kNumPosts = 6;
1851   DummyTaskObserver observer(kNumPosts);
1852
1853   MessageLoop loop;
1854   loop.AddTaskObserver(&observer);
1855   loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, kNumPosts));
1856   loop.Run();
1857   loop.RemoveTaskObserver(&observer);
1858
1859   EXPECT_EQ(kNumPosts, observer.num_tasks_started());
1860   EXPECT_EQ(kNumPosts, observer.num_tasks_processed());
1861 }
1862
1863 #if defined(OS_WIN)
1864 TEST(MessageLoopTest, Dispatcher) {
1865   // This test requires a UI loop
1866   RunTest_Dispatcher(MessageLoop::TYPE_UI);
1867 }
1868
1869 TEST(MessageLoopTest, DispatcherWithMessageHook) {
1870   // This test requires a UI loop
1871   RunTest_DispatcherWithMessageHook(MessageLoop::TYPE_UI);
1872 }
1873
1874 TEST(MessageLoopTest, IOHandler) {
1875   RunTest_IOHandler();
1876 }
1877
1878 TEST(MessageLoopTest, WaitForIO) {
1879   RunTest_WaitForIO();
1880 }
1881
1882 TEST(MessageLoopTest, HighResolutionTimer) {
1883   MessageLoop loop;
1884
1885   const TimeDelta kFastTimer = TimeDelta::FromMilliseconds(5);
1886   const TimeDelta kSlowTimer = TimeDelta::FromMilliseconds(100);
1887
1888   EXPECT_FALSE(loop.IsHighResolutionTimerEnabledForTesting());
1889
1890   // Post a fast task to enable the high resolution timers.
1891   loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
1892                        kFastTimer);
1893   loop.Run();
1894   EXPECT_TRUE(loop.IsHighResolutionTimerEnabledForTesting());
1895
1896   // Post a slow task and verify high resolution timers
1897   // are still enabled.
1898   loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
1899                        kSlowTimer);
1900   loop.Run();
1901   EXPECT_TRUE(loop.IsHighResolutionTimerEnabledForTesting());
1902
1903   // Wait for a while so that high-resolution mode elapses.
1904   PlatformThread::Sleep(TimeDelta::FromMilliseconds(
1905       MessageLoop::kHighResolutionTimerModeLeaseTimeMs));
1906
1907   // Post a slow task to disable the high resolution timers.
1908   loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
1909                        kSlowTimer);
1910   loop.Run();
1911   EXPECT_FALSE(loop.IsHighResolutionTimerEnabledForTesting());
1912 }
1913
1914 #endif  // defined(OS_WIN)
1915
1916 #if defined(OS_POSIX) && !defined(OS_NACL)
1917
1918 namespace {
1919
1920 class QuitDelegate : public MessageLoopForIO::Watcher {
1921  public:
1922   virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
1923     MessageLoop::current()->QuitWhenIdle();
1924   }
1925   virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
1926     MessageLoop::current()->QuitWhenIdle();
1927   }
1928 };
1929
1930 TEST(MessageLoopTest, FileDescriptorWatcherOutlivesMessageLoop) {
1931   // Simulate a MessageLoop that dies before an FileDescriptorWatcher.
1932   // This could happen when people use the Singleton pattern or atexit.
1933
1934   // Create a file descriptor.  Doesn't need to be readable or writable,
1935   // as we don't need to actually get any notifications.
1936   // pipe() is just the easiest way to do it.
1937   int pipefds[2];
1938   int err = pipe(pipefds);
1939   ASSERT_EQ(0, err);
1940   int fd = pipefds[1];
1941   {
1942     // Arrange for controller to live longer than message loop.
1943     MessageLoopForIO::FileDescriptorWatcher controller;
1944     {
1945       MessageLoopForIO message_loop;
1946
1947       QuitDelegate delegate;
1948       message_loop.WatchFileDescriptor(fd,
1949           true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate);
1950       // and don't run the message loop, just destroy it.
1951     }
1952   }
1953   if (HANDLE_EINTR(close(pipefds[0])) < 0)
1954     PLOG(ERROR) << "close";
1955   if (HANDLE_EINTR(close(pipefds[1])) < 0)
1956     PLOG(ERROR) << "close";
1957 }
1958
1959 TEST(MessageLoopTest, FileDescriptorWatcherDoubleStop) {
1960   // Verify that it's ok to call StopWatchingFileDescriptor().
1961   // (Errors only showed up in valgrind.)
1962   int pipefds[2];
1963   int err = pipe(pipefds);
1964   ASSERT_EQ(0, err);
1965   int fd = pipefds[1];
1966   {
1967     // Arrange for message loop to live longer than controller.
1968     MessageLoopForIO message_loop;
1969     {
1970       MessageLoopForIO::FileDescriptorWatcher controller;
1971
1972       QuitDelegate delegate;
1973       message_loop.WatchFileDescriptor(fd,
1974           true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate);
1975       controller.StopWatchingFileDescriptor();
1976     }
1977   }
1978   if (HANDLE_EINTR(close(pipefds[0])) < 0)
1979     PLOG(ERROR) << "close";
1980   if (HANDLE_EINTR(close(pipefds[1])) < 0)
1981     PLOG(ERROR) << "close";
1982 }
1983
1984 }  // namespace
1985
1986 #endif  // defined(OS_POSIX) && !defined(OS_NACL)
1987
1988 namespace {
1989 // Inject a test point for recording the destructor calls for Closure objects
1990 // send to MessageLoop::PostTask(). It is awkward usage since we are trying to
1991 // hook the actual destruction, which is not a common operation.
1992 class DestructionObserverProbe :
1993   public RefCounted<DestructionObserverProbe> {
1994  public:
1995   DestructionObserverProbe(bool* task_destroyed,
1996                            bool* destruction_observer_called)
1997       : task_destroyed_(task_destroyed),
1998         destruction_observer_called_(destruction_observer_called) {
1999   }
2000   virtual void Run() {
2001     // This task should never run.
2002     ADD_FAILURE();
2003   }
2004  private:
2005   friend class RefCounted<DestructionObserverProbe>;
2006
2007   virtual ~DestructionObserverProbe() {
2008     EXPECT_FALSE(*destruction_observer_called_);
2009     *task_destroyed_ = true;
2010   }
2011
2012   bool* task_destroyed_;
2013   bool* destruction_observer_called_;
2014 };
2015
2016 class MLDestructionObserver : public MessageLoop::DestructionObserver {
2017  public:
2018   MLDestructionObserver(bool* task_destroyed, bool* destruction_observer_called)
2019       : task_destroyed_(task_destroyed),
2020         destruction_observer_called_(destruction_observer_called),
2021         task_destroyed_before_message_loop_(false) {
2022   }
2023   virtual void WillDestroyCurrentMessageLoop() OVERRIDE {
2024     task_destroyed_before_message_loop_ = *task_destroyed_;
2025     *destruction_observer_called_ = true;
2026   }
2027   bool task_destroyed_before_message_loop() const {
2028     return task_destroyed_before_message_loop_;
2029   }
2030  private:
2031   bool* task_destroyed_;
2032   bool* destruction_observer_called_;
2033   bool task_destroyed_before_message_loop_;
2034 };
2035
2036 }  // namespace
2037
2038 TEST(MessageLoopTest, DestructionObserverTest) {
2039   // Verify that the destruction observer gets called at the very end (after
2040   // all the pending tasks have been destroyed).
2041   MessageLoop* loop = new MessageLoop;
2042   const TimeDelta kDelay = TimeDelta::FromMilliseconds(100);
2043
2044   bool task_destroyed = false;
2045   bool destruction_observer_called = false;
2046
2047   MLDestructionObserver observer(&task_destroyed, &destruction_observer_called);
2048   loop->AddDestructionObserver(&observer);
2049   loop->PostDelayedTask(
2050       FROM_HERE,
2051       Bind(&DestructionObserverProbe::Run,
2052                  new DestructionObserverProbe(&task_destroyed,
2053                                               &destruction_observer_called)),
2054       kDelay);
2055   delete loop;
2056   EXPECT_TRUE(observer.task_destroyed_before_message_loop());
2057   // The task should have been destroyed when we deleted the loop.
2058   EXPECT_TRUE(task_destroyed);
2059   EXPECT_TRUE(destruction_observer_called);
2060 }
2061
2062
2063 // Verify that MessageLoop sets ThreadMainTaskRunner::current() and it
2064 // posts tasks on that message loop.
2065 TEST(MessageLoopTest, ThreadMainTaskRunner) {
2066   MessageLoop loop;
2067
2068   scoped_refptr<Foo> foo(new Foo());
2069   std::string a("a");
2070   ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, Bind(
2071       &Foo::Test1ConstRef, foo.get(), a));
2072
2073   // Post quit task;
2074   MessageLoop::current()->PostTask(FROM_HERE, Bind(
2075       &MessageLoop::Quit, Unretained(MessageLoop::current())));
2076
2077   // Now kick things off
2078   MessageLoop::current()->Run();
2079
2080   EXPECT_EQ(foo->test_count(), 1);
2081   EXPECT_EQ(foo->result(), "a");
2082 }
2083
2084 TEST(MessageLoopTest, IsType) {
2085   MessageLoop loop(MessageLoop::TYPE_UI);
2086   EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI));
2087   EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO));
2088   EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT));
2089 }
2090
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