Home | History | Annotate | Download | only in message_loop
      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 const wchar_t* const kMessageBoxTitle = L"MessageLoop Unit Test";
    613 
    614 enum TaskType {
    615   MESSAGEBOX,
    616   ENDDIALOG,
    617   RECURSIVE,
    618   TIMEDMESSAGELOOP,
    619   QUITMESSAGELOOP,
    620   ORDERED,
    621   PUMPS,
    622   SLEEP,
    623   RUNS,
    624 };
    625 
    626 // Saves the order in which the tasks executed.
    627 struct TaskItem {
    628   TaskItem(TaskType t, int c, bool s)
    629       : type(t),
    630         cookie(c),
    631         start(s) {
    632   }
    633 
    634   TaskType type;
    635   int cookie;
    636   bool start;
    637 
    638   bool operator == (const TaskItem& other) const {
    639     return type == other.type && cookie == other.cookie && start == other.start;
    640   }
    641 };
    642 
    643 std::ostream& operator <<(std::ostream& os, TaskType type) {
    644   switch (type) {
    645   case MESSAGEBOX:        os << "MESSAGEBOX"; break;
    646   case ENDDIALOG:         os << "ENDDIALOG"; break;
    647   case RECURSIVE:         os << "RECURSIVE"; break;
    648   case TIMEDMESSAGELOOP:  os << "TIMEDMESSAGELOOP"; break;
    649   case QUITMESSAGELOOP:   os << "QUITMESSAGELOOP"; break;
    650   case ORDERED:          os << "ORDERED"; break;
    651   case PUMPS:             os << "PUMPS"; break;
    652   case SLEEP:             os << "SLEEP"; break;
    653   default:
    654     NOTREACHED();
    655     os << "Unknown TaskType";
    656     break;
    657   }
    658   return os;
    659 }
    660 
    661 std::ostream& operator <<(std::ostream& os, const TaskItem& item) {
    662   if (item.start)
    663     return os << item.type << " " << item.cookie << " starts";
    664   else
    665     return os << item.type << " " << item.cookie << " ends";
    666 }
    667 
    668 class TaskList {
    669  public:
    670   void RecordStart(TaskType type, int cookie) {
    671     TaskItem item(type, cookie, true);
    672     DVLOG(1) << item;
    673     task_list_.push_back(item);
    674   }
    675 
    676   void RecordEnd(TaskType type, int cookie) {
    677     TaskItem item(type, cookie, false);
    678     DVLOG(1) << item;
    679     task_list_.push_back(item);
    680   }
    681 
    682   size_t Size() {
    683     return task_list_.size();
    684   }
    685 
    686   TaskItem Get(int n)  {
    687     return task_list_[n];
    688   }
    689 
    690  private:
    691   std::vector<TaskItem> task_list_;
    692 };
    693 
    694 // Saves the order the tasks ran.
    695 void OrderedFunc(TaskList* order, int cookie) {
    696   order->RecordStart(ORDERED, cookie);
    697   order->RecordEnd(ORDERED, cookie);
    698 }
    699 
    700 #if defined(OS_WIN)
    701 
    702 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes,
    703 // common controls (like OpenFile) and StartDoc printing function can cause
    704 // implicit message loops.
    705 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) {
    706   order->RecordStart(MESSAGEBOX, cookie);
    707   if (is_reentrant)
    708     MessageLoop::current()->SetNestableTasksAllowed(true);
    709   MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK);
    710   order->RecordEnd(MESSAGEBOX, cookie);
    711 }
    712 
    713 // Will end the MessageBox.
    714 void EndDialogFunc(TaskList* order, int cookie) {
    715   order->RecordStart(ENDDIALOG, cookie);
    716   HWND window = GetActiveWindow();
    717   if (window != NULL) {
    718     EXPECT_NE(EndDialog(window, IDCONTINUE), 0);
    719     // Cheap way to signal that the window wasn't found if RunEnd() isn't
    720     // called.
    721     order->RecordEnd(ENDDIALOG, cookie);
    722   }
    723 }
    724 
    725 #endif  // defined(OS_WIN)
    726 
    727 void RecursiveFunc(TaskList* order, int cookie, int depth,
    728                    bool is_reentrant) {
    729   order->RecordStart(RECURSIVE, cookie);
    730   if (depth > 0) {
    731     if (is_reentrant)
    732       MessageLoop::current()->SetNestableTasksAllowed(true);
    733     MessageLoop::current()->PostTask(
    734         FROM_HERE,
    735         Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant));
    736   }
    737   order->RecordEnd(RECURSIVE, cookie);
    738 }
    739 
    740 void RecursiveSlowFunc(TaskList* order, int cookie, int depth,
    741                        bool is_reentrant) {
    742   RecursiveFunc(order, cookie, depth, is_reentrant);
    743   PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));
    744 }
    745 
    746 void QuitFunc(TaskList* order, int cookie) {
    747   order->RecordStart(QUITMESSAGELOOP, cookie);
    748   MessageLoop::current()->QuitWhenIdle();
    749   order->RecordEnd(QUITMESSAGELOOP, cookie);
    750 }
    751 
    752 void SleepFunc(TaskList* order, int cookie, TimeDelta delay) {
    753   order->RecordStart(SLEEP, cookie);
    754   PlatformThread::Sleep(delay);
    755   order->RecordEnd(SLEEP, cookie);
    756 }
    757 
    758 #if defined(OS_WIN)
    759 void RecursiveFuncWin(MessageLoop* target,
    760                       HANDLE event,
    761                       bool expect_window,
    762                       TaskList* order,
    763                       bool is_reentrant) {
    764   target->PostTask(FROM_HERE,
    765                    Bind(&RecursiveFunc, order, 1, 2, is_reentrant));
    766   target->PostTask(FROM_HERE,
    767                    Bind(&MessageBoxFunc, order, 2, is_reentrant));
    768   target->PostTask(FROM_HERE,
    769                    Bind(&RecursiveFunc, order, 3, 2, is_reentrant));
    770   // The trick here is that for recursive task processing, this task will be
    771   // ran _inside_ the MessageBox message loop, dismissing the MessageBox
    772   // without a chance.
    773   // For non-recursive task processing, this will be executed _after_ the
    774   // MessageBox will have been dismissed by the code below, where
    775   // expect_window_ is true.
    776   target->PostTask(FROM_HERE,
    777                    Bind(&EndDialogFunc, order, 4));
    778   target->PostTask(FROM_HERE,
    779                    Bind(&QuitFunc, order, 5));
    780 
    781   // Enforce that every tasks are sent before starting to run the main thread
    782   // message loop.
    783   ASSERT_TRUE(SetEvent(event));
    784 
    785   // Poll for the MessageBox. Don't do this at home! At the speed we do it,
    786   // you will never realize one MessageBox was shown.
    787   for (; expect_window;) {
    788     HWND window = FindWindow(L"#32770", kMessageBoxTitle);
    789     if (window) {
    790       // Dismiss it.
    791       for (;;) {
    792         HWND button = FindWindowEx(window, NULL, L"Button", NULL);
    793         if (button != NULL) {
    794           EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0));
    795           EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0));
    796           break;
    797         }
    798       }
    799       break;
    800     }
    801   }
    802 }
    803 
    804 #endif  // defined(OS_WIN)
    805 
    806 void RunTest_RecursiveDenial1(MessageLoop::Type message_loop_type) {
    807   MessageLoop loop(message_loop_type);
    808 
    809   EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed());
    810   TaskList order;
    811   MessageLoop::current()->PostTask(
    812       FROM_HERE,
    813       Bind(&RecursiveFunc, &order, 1, 2, false));
    814   MessageLoop::current()->PostTask(
    815       FROM_HERE,
    816       Bind(&RecursiveFunc, &order, 2, 2, false));
    817   MessageLoop::current()->PostTask(
    818       FROM_HERE,
    819       Bind(&QuitFunc, &order, 3));
    820 
    821   MessageLoop::current()->Run();
    822 
    823   // FIFO order.
    824   ASSERT_EQ(14U, order.Size());
    825   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
    826   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
    827   EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
    828   EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
    829   EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
    830   EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
    831   EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true));
    832   EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false));
    833   EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
    834   EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
    835   EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
    836   EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
    837   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true));
    838   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false));
    839 }
    840 
    841 void RunTest_RecursiveDenial3(MessageLoop::Type message_loop_type) {
    842   MessageLoop loop(message_loop_type);
    843 
    844   EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed());
    845   TaskList order;
    846   MessageLoop::current()->PostTask(
    847       FROM_HERE, Bind(&RecursiveSlowFunc, &order, 1, 2, false));
    848   MessageLoop::current()->PostTask(
    849       FROM_HERE, Bind(&RecursiveSlowFunc, &order, 2, 2, false));
    850   MessageLoop::current()->PostDelayedTask(
    851       FROM_HERE,
    852       Bind(&OrderedFunc, &order, 3),
    853       TimeDelta::FromMilliseconds(5));
    854   MessageLoop::current()->PostDelayedTask(
    855       FROM_HERE,
    856       Bind(&QuitFunc, &order, 4),
    857       TimeDelta::FromMilliseconds(5));
    858 
    859   MessageLoop::current()->Run();
    860 
    861   // FIFO order.
    862   ASSERT_EQ(16U, order.Size());
    863   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
    864   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
    865   EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
    866   EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
    867   EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 1, true));
    868   EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 1, false));
    869   EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 3, true));
    870   EXPECT_EQ(order.Get(7), TaskItem(ORDERED, 3, false));
    871   EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
    872   EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
    873   EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 4, true));
    874   EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 4, false));
    875   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 1, true));
    876   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, false));
    877   EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 2, true));
    878   EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 2, false));
    879 }
    880 
    881 void RunTest_RecursiveSupport1(MessageLoop::Type message_loop_type) {
    882   MessageLoop loop(message_loop_type);
    883 
    884   TaskList order;
    885   MessageLoop::current()->PostTask(
    886       FROM_HERE, Bind(&RecursiveFunc, &order, 1, 2, true));
    887   MessageLoop::current()->PostTask(
    888       FROM_HERE, Bind(&RecursiveFunc, &order, 2, 2, true));
    889   MessageLoop::current()->PostTask(
    890       FROM_HERE, Bind(&QuitFunc, &order, 3));
    891 
    892   MessageLoop::current()->Run();
    893 
    894   // FIFO order.
    895   ASSERT_EQ(14U, order.Size());
    896   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
    897   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
    898   EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
    899   EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
    900   EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
    901   EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
    902   EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true));
    903   EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false));
    904   EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
    905   EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
    906   EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
    907   EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
    908   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true));
    909   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false));
    910 }
    911 
    912 #if defined(OS_WIN)
    913 // TODO(darin): These tests need to be ported since they test critical
    914 // message loop functionality.
    915 
    916 // A side effect of this test is the generation a beep. Sorry.
    917 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) {
    918   MessageLoop loop(message_loop_type);
    919 
    920   Thread worker("RecursiveDenial2_worker");
    921   Thread::Options options;
    922   options.message_loop_type = message_loop_type;
    923   ASSERT_EQ(true, worker.StartWithOptions(options));
    924   TaskList order;
    925   win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
    926   worker.message_loop()->PostTask(FROM_HERE,
    927                                   Bind(&RecursiveFuncWin,
    928                                              MessageLoop::current(),
    929                                              event.Get(),
    930                                              true,
    931                                              &order,
    932                                              false));
    933   // Let the other thread execute.
    934   WaitForSingleObject(event, INFINITE);
    935   MessageLoop::current()->Run();
    936 
    937   ASSERT_EQ(order.Size(), 17);
    938   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
    939   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
    940   EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true));
    941   EXPECT_EQ(order.Get(3), TaskItem(MESSAGEBOX, 2, false));
    942   EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, true));
    943   EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 3, false));
    944   // When EndDialogFunc is processed, the window is already dismissed, hence no
    945   // "end" entry.
    946   EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, true));
    947   EXPECT_EQ(order.Get(7), TaskItem(QUITMESSAGELOOP, 5, true));
    948   EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, false));
    949   EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 1, true));
    950   EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, false));
    951   EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 3, true));
    952   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, false));
    953   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, true));
    954   EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, false));
    955   EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 3, true));
    956   EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, false));
    957 }
    958 
    959 // A side effect of this test is the generation a beep. Sorry.  This test also
    960 // needs to process windows messages on the current thread.
    961 void RunTest_RecursiveSupport2(MessageLoop::Type message_loop_type) {
    962   MessageLoop loop(message_loop_type);
    963 
    964   Thread worker("RecursiveSupport2_worker");
    965   Thread::Options options;
    966   options.message_loop_type = message_loop_type;
    967   ASSERT_EQ(true, worker.StartWithOptions(options));
    968   TaskList order;
    969   win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
    970   worker.message_loop()->PostTask(FROM_HERE,
    971                                   Bind(&RecursiveFuncWin,
    972                                              MessageLoop::current(),
    973                                              event.Get(),
    974                                              false,
    975                                              &order,
    976                                              true));
    977   // Let the other thread execute.
    978   WaitForSingleObject(event, INFINITE);
    979   MessageLoop::current()->Run();
    980 
    981   ASSERT_EQ(order.Size(), 18);
    982   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
    983   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
    984   EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true));
    985   // Note that this executes in the MessageBox modal loop.
    986   EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 3, true));
    987   EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, false));
    988   EXPECT_EQ(order.Get(5), TaskItem(ENDDIALOG, 4, true));
    989   EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, false));
    990   EXPECT_EQ(order.Get(7), TaskItem(MESSAGEBOX, 2, false));
    991   /* The order can subtly change here. The reason is that when RecursiveFunc(1)
    992      is called in the main thread, if it is faster than getting to the
    993      PostTask(FROM_HERE, Bind(&QuitFunc) execution, the order of task
    994      execution can change. We don't care anyway that the order isn't correct.
    995   EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, true));
    996   EXPECT_EQ(order.Get(9), TaskItem(QUITMESSAGELOOP, 5, false));
    997   EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
    998   EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
    999   */
   1000   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true));
   1001   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false));
   1002   EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true));
   1003   EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false));
   1004   EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true));
   1005   EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false));
   1006 }
   1007 
   1008 #endif  // defined(OS_WIN)
   1009 
   1010 void FuncThatPumps(TaskList* order, int cookie) {
   1011   order->RecordStart(PUMPS, cookie);
   1012   {
   1013     MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
   1014     RunLoop().RunUntilIdle();
   1015   }
   1016   order->RecordEnd(PUMPS, cookie);
   1017 }
   1018 
   1019 void FuncThatRuns(TaskList* order, int cookie, RunLoop* run_loop) {
   1020   order->RecordStart(RUNS, cookie);
   1021   {
   1022     MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
   1023     run_loop->Run();
   1024   }
   1025   order->RecordEnd(RUNS, cookie);
   1026 }
   1027 
   1028 void FuncThatQuitsNow() {
   1029   MessageLoop::current()->QuitNow();
   1030 }
   1031 
   1032 // Tests that non nestable tasks run in FIFO if there are no nested loops.
   1033 void RunTest_NonNestableWithNoNesting(
   1034     MessageLoop::Type message_loop_type) {
   1035   MessageLoop loop(message_loop_type);
   1036 
   1037   TaskList order;
   1038 
   1039   MessageLoop::current()->PostNonNestableTask(
   1040       FROM_HERE,
   1041       Bind(&OrderedFunc, &order, 1));
   1042   MessageLoop::current()->PostTask(FROM_HERE,
   1043                                    Bind(&OrderedFunc, &order, 2));
   1044   MessageLoop::current()->PostTask(FROM_HERE,
   1045                                    Bind(&QuitFunc, &order, 3));
   1046   MessageLoop::current()->Run();
   1047 
   1048   // FIFO order.
   1049   ASSERT_EQ(6U, order.Size());
   1050   EXPECT_EQ(order.Get(0), TaskItem(ORDERED, 1, true));
   1051   EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 1, false));
   1052   EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 2, true));
   1053   EXPECT_EQ(order.Get(3), TaskItem(ORDERED, 2, false));
   1054   EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
   1055   EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
   1056 }
   1057 
   1058 // Tests that non nestable tasks don't run when there's code in the call stack.
   1059 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type,
   1060                                      bool use_delayed) {
   1061   MessageLoop loop(message_loop_type);
   1062 
   1063   TaskList order;
   1064 
   1065   MessageLoop::current()->PostTask(
   1066       FROM_HERE,
   1067       Bind(&FuncThatPumps, &order, 1));
   1068   if (use_delayed) {
   1069     MessageLoop::current()->PostNonNestableDelayedTask(
   1070         FROM_HERE,
   1071         Bind(&OrderedFunc, &order, 2),
   1072         TimeDelta::FromMilliseconds(1));
   1073   } else {
   1074     MessageLoop::current()->PostNonNestableTask(
   1075         FROM_HERE,
   1076         Bind(&OrderedFunc, &order, 2));
   1077   }
   1078   MessageLoop::current()->PostTask(FROM_HERE,
   1079                                    Bind(&OrderedFunc, &order, 3));
   1080   MessageLoop::current()->PostTask(
   1081       FROM_HERE,
   1082       Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50)));
   1083   MessageLoop::current()->PostTask(FROM_HERE,
   1084                                    Bind(&OrderedFunc, &order, 5));
   1085   if (use_delayed) {
   1086     MessageLoop::current()->PostNonNestableDelayedTask(
   1087         FROM_HERE,
   1088         Bind(&QuitFunc, &order, 6),
   1089         TimeDelta::FromMilliseconds(2));
   1090   } else {
   1091     MessageLoop::current()->PostNonNestableTask(
   1092         FROM_HERE,
   1093         Bind(&QuitFunc, &order, 6));
   1094   }
   1095 
   1096   MessageLoop::current()->Run();
   1097 
   1098   // FIFO order.
   1099   ASSERT_EQ(12U, order.Size());
   1100   EXPECT_EQ(order.Get(0), TaskItem(PUMPS, 1, true));
   1101   EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 3, true));
   1102   EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 3, false));
   1103   EXPECT_EQ(order.Get(3), TaskItem(SLEEP, 4, true));
   1104   EXPECT_EQ(order.Get(4), TaskItem(SLEEP, 4, false));
   1105   EXPECT_EQ(order.Get(5), TaskItem(ORDERED, 5, true));
   1106   EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 5, false));
   1107   EXPECT_EQ(order.Get(7), TaskItem(PUMPS, 1, false));
   1108   EXPECT_EQ(order.Get(8), TaskItem(ORDERED, 2, true));
   1109   EXPECT_EQ(order.Get(9), TaskItem(ORDERED, 2, false));
   1110   EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 6, true));
   1111   EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 6, false));
   1112 }
   1113 
   1114 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
   1115 void RunTest_QuitNow(MessageLoop::Type message_loop_type) {
   1116   MessageLoop loop(message_loop_type);
   1117 
   1118   TaskList order;
   1119 
   1120   RunLoop run_loop;
   1121 
   1122   MessageLoop::current()->PostTask(FROM_HERE,
   1123       Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop)));
   1124   MessageLoop::current()->PostTask(
   1125       FROM_HERE, Bind(&OrderedFunc, &order, 2));
   1126   MessageLoop::current()->PostTask(
   1127       FROM_HERE, Bind(&FuncThatQuitsNow));
   1128   MessageLoop::current()->PostTask(
   1129       FROM_HERE, Bind(&OrderedFunc, &order, 3));
   1130   MessageLoop::current()->PostTask(
   1131       FROM_HERE, Bind(&FuncThatQuitsNow));
   1132   MessageLoop::current()->PostTask(
   1133       FROM_HERE, Bind(&OrderedFunc, &order, 4)); // never runs
   1134 
   1135   MessageLoop::current()->Run();
   1136 
   1137   ASSERT_EQ(6U, order.Size());
   1138   int task_index = 0;
   1139   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
   1140   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
   1141   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
   1142   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
   1143   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true));
   1144   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false));
   1145   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
   1146 }
   1147 
   1148 // Tests RunLoopQuit works before RunWithID.
   1149 void RunTest_RunLoopQuitOrderBefore(MessageLoop::Type message_loop_type) {
   1150   MessageLoop loop(message_loop_type);
   1151 
   1152   TaskList order;
   1153 
   1154   RunLoop run_loop;
   1155 
   1156   run_loop.Quit();
   1157 
   1158   MessageLoop::current()->PostTask(
   1159       FROM_HERE, Bind(&OrderedFunc, &order, 1)); // never runs
   1160   MessageLoop::current()->PostTask(
   1161       FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs
   1162 
   1163   run_loop.Run();
   1164 
   1165   ASSERT_EQ(0U, order.Size());
   1166 }
   1167 
   1168 // Tests RunLoopQuit works during RunWithID.
   1169 void RunTest_RunLoopQuitOrderDuring(MessageLoop::Type message_loop_type) {
   1170   MessageLoop loop(message_loop_type);
   1171 
   1172   TaskList order;
   1173 
   1174   RunLoop run_loop;
   1175 
   1176   MessageLoop::current()->PostTask(
   1177       FROM_HERE, Bind(&OrderedFunc, &order, 1));
   1178   MessageLoop::current()->PostTask(
   1179       FROM_HERE, run_loop.QuitClosure());
   1180   MessageLoop::current()->PostTask(
   1181       FROM_HERE, Bind(&OrderedFunc, &order, 2)); // never runs
   1182   MessageLoop::current()->PostTask(
   1183       FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs
   1184 
   1185   run_loop.Run();
   1186 
   1187   ASSERT_EQ(2U, order.Size());
   1188   int task_index = 0;
   1189   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, true));
   1190   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, false));
   1191   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
   1192 }
   1193 
   1194 // Tests RunLoopQuit works after RunWithID.
   1195 void RunTest_RunLoopQuitOrderAfter(MessageLoop::Type message_loop_type) {
   1196   MessageLoop loop(message_loop_type);
   1197 
   1198   TaskList order;
   1199 
   1200   RunLoop run_loop;
   1201 
   1202   MessageLoop::current()->PostTask(FROM_HERE,
   1203       Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop)));
   1204   MessageLoop::current()->PostTask(
   1205       FROM_HERE, Bind(&OrderedFunc, &order, 2));
   1206   MessageLoop::current()->PostTask(
   1207       FROM_HERE, Bind(&FuncThatQuitsNow));
   1208   MessageLoop::current()->PostTask(
   1209       FROM_HERE, Bind(&OrderedFunc, &order, 3));
   1210   MessageLoop::current()->PostTask(
   1211       FROM_HERE, run_loop.QuitClosure()); // has no affect
   1212   MessageLoop::current()->PostTask(
   1213       FROM_HERE, Bind(&OrderedFunc, &order, 4));
   1214   MessageLoop::current()->PostTask(
   1215       FROM_HERE, Bind(&FuncThatQuitsNow));
   1216 
   1217   RunLoop outer_run_loop;
   1218   outer_run_loop.Run();
   1219 
   1220   ASSERT_EQ(8U, order.Size());
   1221   int task_index = 0;
   1222   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
   1223   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
   1224   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
   1225   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
   1226   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true));
   1227   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false));
   1228   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, true));
   1229   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, false));
   1230   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
   1231 }
   1232 
   1233 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
   1234 void RunTest_RunLoopQuitTop(MessageLoop::Type message_loop_type) {
   1235   MessageLoop loop(message_loop_type);
   1236 
   1237   TaskList order;
   1238 
   1239   RunLoop outer_run_loop;
   1240   RunLoop nested_run_loop;
   1241 
   1242   MessageLoop::current()->PostTask(FROM_HERE,
   1243       Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
   1244   MessageLoop::current()->PostTask(
   1245       FROM_HERE, outer_run_loop.QuitClosure());
   1246   MessageLoop::current()->PostTask(
   1247       FROM_HERE, Bind(&OrderedFunc, &order, 2));
   1248   MessageLoop::current()->PostTask(
   1249       FROM_HERE, nested_run_loop.QuitClosure());
   1250 
   1251   outer_run_loop.Run();
   1252 
   1253   ASSERT_EQ(4U, order.Size());
   1254   int task_index = 0;
   1255   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
   1256   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
   1257   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
   1258   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
   1259   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
   1260 }
   1261 
   1262 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
   1263 void RunTest_RunLoopQuitNested(MessageLoop::Type message_loop_type) {
   1264   MessageLoop loop(message_loop_type);
   1265 
   1266   TaskList order;
   1267 
   1268   RunLoop outer_run_loop;
   1269   RunLoop nested_run_loop;
   1270 
   1271   MessageLoop::current()->PostTask(FROM_HERE,
   1272       Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
   1273   MessageLoop::current()->PostTask(
   1274       FROM_HERE, nested_run_loop.QuitClosure());
   1275   MessageLoop::current()->PostTask(
   1276       FROM_HERE, Bind(&OrderedFunc, &order, 2));
   1277   MessageLoop::current()->PostTask(
   1278       FROM_HERE, outer_run_loop.QuitClosure());
   1279 
   1280   outer_run_loop.Run();
   1281 
   1282   ASSERT_EQ(4U, order.Size());
   1283   int task_index = 0;
   1284   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
   1285   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
   1286   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
   1287   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
   1288   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
   1289 }
   1290 
   1291 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
   1292 void RunTest_RunLoopQuitBogus(MessageLoop::Type message_loop_type) {
   1293   MessageLoop loop(message_loop_type);
   1294 
   1295   TaskList order;
   1296 
   1297   RunLoop outer_run_loop;
   1298   RunLoop nested_run_loop;
   1299   RunLoop bogus_run_loop;
   1300 
   1301   MessageLoop::current()->PostTask(FROM_HERE,
   1302       Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
   1303   MessageLoop::current()->PostTask(
   1304       FROM_HERE, bogus_run_loop.QuitClosure());
   1305   MessageLoop::current()->PostTask(
   1306       FROM_HERE, Bind(&OrderedFunc, &order, 2));
   1307   MessageLoop::current()->PostTask(
   1308       FROM_HERE, outer_run_loop.QuitClosure());
   1309   MessageLoop::current()->PostTask(
   1310       FROM_HERE, nested_run_loop.QuitClosure());
   1311 
   1312   outer_run_loop.Run();
   1313 
   1314   ASSERT_EQ(4U, order.Size());
   1315   int task_index = 0;
   1316   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
   1317   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
   1318   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
   1319   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
   1320   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
   1321 }
   1322 
   1323 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
   1324 void RunTest_RunLoopQuitDeep(MessageLoop::Type message_loop_type) {
   1325   MessageLoop loop(message_loop_type);
   1326 
   1327   TaskList order;
   1328 
   1329   RunLoop outer_run_loop;
   1330   RunLoop nested_loop1;
   1331   RunLoop nested_loop2;
   1332   RunLoop nested_loop3;
   1333   RunLoop nested_loop4;
   1334 
   1335   MessageLoop::current()->PostTask(FROM_HERE,
   1336       Bind(&FuncThatRuns, &order, 1, Unretained(&nested_loop1)));
   1337   MessageLoop::current()->PostTask(FROM_HERE,
   1338       Bind(&FuncThatRuns, &order, 2, Unretained(&nested_loop2)));
   1339   MessageLoop::current()->PostTask(FROM_HERE,
   1340       Bind(&FuncThatRuns, &order, 3, Unretained(&nested_loop3)));
   1341   MessageLoop::current()->PostTask(FROM_HERE,
   1342       Bind(&FuncThatRuns, &order, 4, Unretained(&nested_loop4)));
   1343   MessageLoop::current()->PostTask(
   1344       FROM_HERE, Bind(&OrderedFunc, &order, 5));
   1345   MessageLoop::current()->PostTask(
   1346       FROM_HERE, outer_run_loop.QuitClosure());
   1347   MessageLoop::current()->PostTask(
   1348       FROM_HERE, Bind(&OrderedFunc, &order, 6));
   1349   MessageLoop::current()->PostTask(
   1350       FROM_HERE, nested_loop1.QuitClosure());
   1351   MessageLoop::current()->PostTask(
   1352       FROM_HERE, Bind(&OrderedFunc, &order, 7));
   1353   MessageLoop::current()->PostTask(
   1354       FROM_HERE, nested_loop2.QuitClosure());
   1355   MessageLoop::current()->PostTask(
   1356       FROM_HERE, Bind(&OrderedFunc, &order, 8));
   1357   MessageLoop::current()->PostTask(
   1358       FROM_HERE, nested_loop3.QuitClosure());
   1359   MessageLoop::current()->PostTask(
   1360       FROM_HERE, Bind(&OrderedFunc, &order, 9));
   1361   MessageLoop::current()->PostTask(
   1362       FROM_HERE, nested_loop4.QuitClosure());
   1363   MessageLoop::current()->PostTask(
   1364       FROM_HERE, Bind(&OrderedFunc, &order, 10));
   1365 
   1366   outer_run_loop.Run();
   1367 
   1368   ASSERT_EQ(18U, order.Size());
   1369   int task_index = 0;
   1370   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
   1371   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, true));
   1372   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, true));
   1373   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, true));
   1374   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, true));
   1375   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, false));
   1376   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 6, true));
   1377   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 6, false));
   1378   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 7, true));
   1379   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 7, false));
   1380   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 8, true));
   1381   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 8, false));
   1382   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 9, true));
   1383   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 9, false));
   1384   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, false));
   1385   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, false));
   1386   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, false));
   1387   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
   1388   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
   1389 }
   1390 
   1391 void PostNTasksThenQuit(int posts_remaining) {
   1392   if (posts_remaining > 1) {
   1393     MessageLoop::current()->PostTask(
   1394         FROM_HERE,
   1395         Bind(&PostNTasksThenQuit, posts_remaining - 1));
   1396   } else {
   1397     MessageLoop::current()->QuitWhenIdle();
   1398   }
   1399 }
   1400 
   1401 void RunTest_RecursivePosts(MessageLoop::Type message_loop_type,
   1402                             int num_times) {
   1403   MessageLoop loop(message_loop_type);
   1404   loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, num_times));
   1405   loop.Run();
   1406 }
   1407 
   1408 #if defined(OS_WIN)
   1409 
   1410 class DispatcherImpl : public MessageLoopForUI::Dispatcher {
   1411  public:
   1412   DispatcherImpl() : dispatch_count_(0) {}
   1413 
   1414   virtual bool Dispatch(const NativeEvent& msg) OVERRIDE {
   1415     ::TranslateMessage(&msg);
   1416     ::DispatchMessage(&msg);
   1417     // Do not count WM_TIMER since it is not what we post and it will cause
   1418     // flakiness.
   1419     if (msg.message != WM_TIMER)
   1420       ++dispatch_count_;
   1421     // We treat WM_LBUTTONUP as the last message.
   1422     return msg.message != WM_LBUTTONUP;
   1423   }
   1424 
   1425   int dispatch_count_;
   1426 };
   1427 
   1428 void MouseDownUp() {
   1429   PostMessage(NULL, WM_LBUTTONDOWN, 0, 0);
   1430   PostMessage(NULL, WM_LBUTTONUP, 'A', 0);
   1431 }
   1432 
   1433 void RunTest_Dispatcher(MessageLoop::Type message_loop_type) {
   1434   MessageLoop loop(message_loop_type);
   1435 
   1436   MessageLoop::current()->PostDelayedTask(
   1437       FROM_HERE,
   1438       Bind(&MouseDownUp),
   1439       TimeDelta::FromMilliseconds(100));
   1440   DispatcherImpl dispatcher;
   1441   RunLoop run_loop(&dispatcher);
   1442   run_loop.Run();
   1443   ASSERT_EQ(2, dispatcher.dispatch_count_);
   1444 }
   1445 
   1446 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) {
   1447   if (code == MessagePumpForUI::kMessageFilterCode) {
   1448     MSG* msg = reinterpret_cast<MSG*>(lparam);
   1449     if (msg->message == WM_LBUTTONDOWN)
   1450       return TRUE;
   1451   }
   1452   return FALSE;
   1453 }
   1454 
   1455 void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) {
   1456   MessageLoop loop(message_loop_type);
   1457 
   1458   MessageLoop::current()->PostDelayedTask(
   1459       FROM_HERE,
   1460       Bind(&MouseDownUp),
   1461       TimeDelta::FromMilliseconds(100));
   1462   HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER,
   1463                                     MsgFilterProc,
   1464                                     NULL,
   1465                                     GetCurrentThreadId());
   1466   DispatcherImpl dispatcher;
   1467   RunLoop run_loop(&dispatcher);
   1468   run_loop.Run();
   1469   ASSERT_EQ(1, dispatcher.dispatch_count_);
   1470   UnhookWindowsHookEx(msg_hook);
   1471 }
   1472 
   1473 class TestIOHandler : public MessageLoopForIO::IOHandler {
   1474  public:
   1475   TestIOHandler(const wchar_t* name, HANDLE signal, bool wait);
   1476 
   1477   virtual void OnIOCompleted(MessageLoopForIO::IOContext* context,
   1478                              DWORD bytes_transfered, DWORD error);
   1479 
   1480   void Init();
   1481   void WaitForIO();
   1482   OVERLAPPED* context() { return &context_.overlapped; }
   1483   DWORD size() { return sizeof(buffer_); }
   1484 
   1485  private:
   1486   char buffer_[48];
   1487   MessageLoopForIO::IOContext context_;
   1488   HANDLE signal_;
   1489   win::ScopedHandle file_;
   1490   bool wait_;
   1491 };
   1492 
   1493 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait)
   1494     : signal_(signal), wait_(wait) {
   1495   memset(buffer_, 0, sizeof(buffer_));
   1496   memset(&context_, 0, sizeof(context_));
   1497   context_.handler = this;
   1498 
   1499   file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
   1500                        FILE_FLAG_OVERLAPPED, NULL));
   1501   EXPECT_TRUE(file_.IsValid());
   1502 }
   1503 
   1504 void TestIOHandler::Init() {
   1505   MessageLoopForIO::current()->RegisterIOHandler(file_, this);
   1506 
   1507   DWORD read;
   1508   EXPECT_FALSE(ReadFile(file_, buffer_, size(), &read, context()));
   1509   EXPECT_EQ(ERROR_IO_PENDING, GetLastError());
   1510   if (wait_)
   1511     WaitForIO();
   1512 }
   1513 
   1514 void TestIOHandler::OnIOCompleted(MessageLoopForIO::IOContext* context,
   1515                                   DWORD bytes_transfered, DWORD error) {
   1516   ASSERT_TRUE(context == &context_);
   1517   ASSERT_TRUE(SetEvent(signal_));
   1518 }
   1519 
   1520 void TestIOHandler::WaitForIO() {
   1521   EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this));
   1522   EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this));
   1523 }
   1524 
   1525 void RunTest_IOHandler() {
   1526   win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL));
   1527   ASSERT_TRUE(callback_called.IsValid());
   1528 
   1529   const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe";
   1530   win::ScopedHandle server(
   1531       CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
   1532   ASSERT_TRUE(server.IsValid());
   1533 
   1534   Thread thread("IOHandler test");
   1535   Thread::Options options;
   1536   options.message_loop_type = MessageLoop::TYPE_IO;
   1537   ASSERT_TRUE(thread.StartWithOptions(options));
   1538 
   1539   MessageLoop* thread_loop = thread.message_loop();
   1540   ASSERT_TRUE(NULL != thread_loop);
   1541 
   1542   TestIOHandler handler(kPipeName, callback_called, false);
   1543   thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
   1544                                               Unretained(&handler)));
   1545   // Make sure the thread runs and sleeps for lack of work.
   1546   PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
   1547 
   1548   const char buffer[] = "Hello there!";
   1549   DWORD written;
   1550   EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL));
   1551 
   1552   DWORD result = WaitForSingleObject(callback_called, 1000);
   1553   EXPECT_EQ(WAIT_OBJECT_0, result);
   1554 
   1555   thread.Stop();
   1556 }
   1557 
   1558 void RunTest_WaitForIO() {
   1559   win::ScopedHandle callback1_called(
   1560       CreateEvent(NULL, TRUE, FALSE, NULL));
   1561   win::ScopedHandle callback2_called(
   1562       CreateEvent(NULL, TRUE, FALSE, NULL));
   1563   ASSERT_TRUE(callback1_called.IsValid());
   1564   ASSERT_TRUE(callback2_called.IsValid());
   1565 
   1566   const wchar_t* kPipeName1 = L"\\\\.\\pipe\\iohandler_pipe1";
   1567   const wchar_t* kPipeName2 = L"\\\\.\\pipe\\iohandler_pipe2";
   1568   win::ScopedHandle server1(
   1569       CreateNamedPipe(kPipeName1, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
   1570   win::ScopedHandle server2(
   1571       CreateNamedPipe(kPipeName2, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL));
   1572   ASSERT_TRUE(server1.IsValid());
   1573   ASSERT_TRUE(server2.IsValid());
   1574 
   1575   Thread thread("IOHandler test");
   1576   Thread::Options options;
   1577   options.message_loop_type = MessageLoop::TYPE_IO;
   1578   ASSERT_TRUE(thread.StartWithOptions(options));
   1579 
   1580   MessageLoop* thread_loop = thread.message_loop();
   1581   ASSERT_TRUE(NULL != thread_loop);
   1582 
   1583   TestIOHandler handler1(kPipeName1, callback1_called, false);
   1584   TestIOHandler handler2(kPipeName2, callback2_called, true);
   1585   thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
   1586                                               Unretained(&handler1)));
   1587   // TODO(ajwong): Do we really need such long Sleeps in ths function?
   1588   // Make sure the thread runs and sleeps for lack of work.
   1589   TimeDelta delay = TimeDelta::FromMilliseconds(100);
   1590   PlatformThread::Sleep(delay);
   1591   thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init,
   1592                                               Unretained(&handler2)));
   1593   PlatformThread::Sleep(delay);
   1594 
   1595   // At this time handler1 is waiting to be called, and the thread is waiting
   1596   // on the Init method of handler2, filtering only handler2 callbacks.
   1597 
   1598   const char buffer[] = "Hello there!";
   1599   DWORD written;
   1600   EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL));
   1601   PlatformThread::Sleep(2 * delay);
   1602   EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) <<
   1603       "handler1 has not been called";
   1604 
   1605   EXPECT_TRUE(WriteFile(server2, buffer, sizeof(buffer), &written, NULL));
   1606 
   1607   HANDLE objects[2] = { callback1_called.Get(), callback2_called.Get() };
   1608   DWORD result = WaitForMultipleObjects(2, objects, TRUE, 1000);
   1609   EXPECT_EQ(WAIT_OBJECT_0, result);
   1610 
   1611   thread.Stop();
   1612 }
   1613 
   1614 #endif  // defined(OS_WIN)
   1615 
   1616 }  // namespace
   1617 
   1618 //-----------------------------------------------------------------------------
   1619 // Each test is run against each type of MessageLoop.  That way we are sure
   1620 // that message loops work properly in all configurations.  Of course, in some
   1621 // cases, a unit test may only be for a particular type of loop.
   1622 
   1623 TEST(MessageLoopTest, PostTask) {
   1624   RunTest_PostTask(MessageLoop::TYPE_DEFAULT);
   1625   RunTest_PostTask(MessageLoop::TYPE_UI);
   1626   RunTest_PostTask(MessageLoop::TYPE_IO);
   1627 }
   1628 
   1629 TEST(MessageLoopTest, PostTask_SEH) {
   1630   RunTest_PostTask_SEH(MessageLoop::TYPE_DEFAULT);
   1631   RunTest_PostTask_SEH(MessageLoop::TYPE_UI);
   1632   RunTest_PostTask_SEH(MessageLoop::TYPE_IO);
   1633 }
   1634 
   1635 TEST(MessageLoopTest, PostDelayedTask_Basic) {
   1636   RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_DEFAULT);
   1637   RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_UI);
   1638   RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_IO);
   1639 }
   1640 
   1641 TEST(MessageLoopTest, PostDelayedTask_InDelayOrder) {
   1642   RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_DEFAULT);
   1643   RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_UI);
   1644   RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_IO);
   1645 }
   1646 
   1647 TEST(MessageLoopTest, PostDelayedTask_InPostOrder) {
   1648   RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_DEFAULT);
   1649   RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_UI);
   1650   RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_IO);
   1651 }
   1652 
   1653 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_2) {
   1654   RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_DEFAULT);
   1655   RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_UI);
   1656   RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_IO);
   1657 }
   1658 
   1659 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_3) {
   1660   RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_DEFAULT);
   1661   RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_UI);
   1662   RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_IO);
   1663 }
   1664 
   1665 TEST(MessageLoopTest, PostDelayedTask_SharedTimer) {
   1666   RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_DEFAULT);
   1667   RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_UI);
   1668   RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_IO);
   1669 }
   1670 
   1671 #if defined(OS_WIN)
   1672 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) {
   1673   RunTest_PostDelayedTask_SharedTimer_SubPump();
   1674 }
   1675 #endif
   1676 
   1677 // TODO(darin): MessageLoop does not support deleting all tasks in the
   1678 // destructor.
   1679 // Fails, http://crbug.com/50272.
   1680 TEST(MessageLoopTest, DISABLED_EnsureDeletion) {
   1681   RunTest_EnsureDeletion(MessageLoop::TYPE_DEFAULT);
   1682   RunTest_EnsureDeletion(MessageLoop::TYPE_UI);
   1683   RunTest_EnsureDeletion(MessageLoop::TYPE_IO);
   1684 }
   1685 
   1686 // TODO(darin): MessageLoop does not support deleting all tasks in the
   1687 // destructor.
   1688 // Fails, http://crbug.com/50272.
   1689 TEST(MessageLoopTest, DISABLED_EnsureDeletion_Chain) {
   1690   RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_DEFAULT);
   1691   RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_UI);
   1692   RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_IO);
   1693 }
   1694 
   1695 #if defined(OS_WIN)
   1696 TEST(MessageLoopTest, Crasher) {
   1697   RunTest_Crasher(MessageLoop::TYPE_DEFAULT);
   1698   RunTest_Crasher(MessageLoop::TYPE_UI);
   1699   RunTest_Crasher(MessageLoop::TYPE_IO);
   1700 }
   1701 
   1702 TEST(MessageLoopTest, CrasherNasty) {
   1703   RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT);
   1704   RunTest_CrasherNasty(MessageLoop::TYPE_UI);
   1705   RunTest_CrasherNasty(MessageLoop::TYPE_IO);
   1706 }
   1707 #endif  // defined(OS_WIN)
   1708 
   1709 TEST(MessageLoopTest, Nesting) {
   1710   RunTest_Nesting(MessageLoop::TYPE_DEFAULT);
   1711   RunTest_Nesting(MessageLoop::TYPE_UI);
   1712   RunTest_Nesting(MessageLoop::TYPE_IO);
   1713 }
   1714 
   1715 TEST(MessageLoopTest, RecursiveDenial1) {
   1716   RunTest_RecursiveDenial1(MessageLoop::TYPE_DEFAULT);
   1717   RunTest_RecursiveDenial1(MessageLoop::TYPE_UI);
   1718   RunTest_RecursiveDenial1(MessageLoop::TYPE_IO);
   1719 }
   1720 
   1721 TEST(MessageLoopTest, RecursiveDenial3) {
   1722   RunTest_RecursiveDenial3(MessageLoop::TYPE_DEFAULT);
   1723   RunTest_RecursiveDenial3(MessageLoop::TYPE_UI);
   1724   RunTest_RecursiveDenial3(MessageLoop::TYPE_IO);
   1725 }
   1726 
   1727 TEST(MessageLoopTest, RecursiveSupport1) {
   1728   RunTest_RecursiveSupport1(MessageLoop::TYPE_DEFAULT);
   1729   RunTest_RecursiveSupport1(MessageLoop::TYPE_UI);
   1730   RunTest_RecursiveSupport1(MessageLoop::TYPE_IO);
   1731 }
   1732 
   1733 #if defined(OS_WIN)
   1734 // This test occasionally hangs http://crbug.com/44567
   1735 TEST(MessageLoopTest, DISABLED_RecursiveDenial2) {
   1736   RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT);
   1737   RunTest_RecursiveDenial2(MessageLoop::TYPE_UI);
   1738   RunTest_RecursiveDenial2(MessageLoop::TYPE_IO);
   1739 }
   1740 
   1741 TEST(MessageLoopTest, RecursiveSupport2) {
   1742   // This test requires a UI loop
   1743   RunTest_RecursiveSupport2(MessageLoop::TYPE_UI);
   1744 }
   1745 #endif  // defined(OS_WIN)
   1746 
   1747 TEST(MessageLoopTest, NonNestableWithNoNesting) {
   1748   RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_DEFAULT);
   1749   RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_UI);
   1750   RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_IO);
   1751 }
   1752 
   1753 TEST(MessageLoopTest, NonNestableInNestedLoop) {
   1754   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, false);
   1755   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, false);
   1756   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, false);
   1757 }
   1758 
   1759 TEST(MessageLoopTest, NonNestableDelayedInNestedLoop) {
   1760   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, true);
   1761   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, true);
   1762   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, true);
   1763 }
   1764 
   1765 TEST(MessageLoopTest, QuitNow) {
   1766   RunTest_QuitNow(MessageLoop::TYPE_DEFAULT);
   1767   RunTest_QuitNow(MessageLoop::TYPE_UI);
   1768   RunTest_QuitNow(MessageLoop::TYPE_IO);
   1769 }
   1770 
   1771 TEST(MessageLoopTest, RunLoopQuitTop) {
   1772   RunTest_RunLoopQuitTop(MessageLoop::TYPE_DEFAULT);
   1773   RunTest_RunLoopQuitTop(MessageLoop::TYPE_UI);
   1774   RunTest_RunLoopQuitTop(MessageLoop::TYPE_IO);
   1775 }
   1776 
   1777 TEST(MessageLoopTest, RunLoopQuitNested) {
   1778   RunTest_RunLoopQuitNested(MessageLoop::TYPE_DEFAULT);
   1779   RunTest_RunLoopQuitNested(MessageLoop::TYPE_UI);
   1780   RunTest_RunLoopQuitNested(MessageLoop::TYPE_IO);
   1781 }
   1782 
   1783 TEST(MessageLoopTest, RunLoopQuitBogus) {
   1784   RunTest_RunLoopQuitBogus(MessageLoop::TYPE_DEFAULT);
   1785   RunTest_RunLoopQuitBogus(MessageLoop::TYPE_UI);
   1786   RunTest_RunLoopQuitBogus(MessageLoop::TYPE_IO);
   1787 }
   1788 
   1789 TEST(MessageLoopTest, RunLoopQuitDeep) {
   1790   RunTest_RunLoopQuitDeep(MessageLoop::TYPE_DEFAULT);
   1791   RunTest_RunLoopQuitDeep(MessageLoop::TYPE_UI);
   1792   RunTest_RunLoopQuitDeep(MessageLoop::TYPE_IO);
   1793 }
   1794 
   1795 TEST(MessageLoopTest, RunLoopQuitOrderBefore) {
   1796   RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_DEFAULT);
   1797   RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_UI);
   1798   RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_IO);
   1799 }
   1800 
   1801 TEST(MessageLoopTest, RunLoopQuitOrderDuring) {
   1802   RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_DEFAULT);
   1803   RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_UI);
   1804   RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_IO);
   1805 }
   1806 
   1807 TEST(MessageLoopTest, RunLoopQuitOrderAfter) {
   1808   RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_DEFAULT);
   1809   RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_UI);
   1810   RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_IO);
   1811 }
   1812 
   1813 class DummyTaskObserver : public MessageLoop::TaskObserver {
   1814  public:
   1815   explicit DummyTaskObserver(int num_tasks)
   1816       : num_tasks_started_(0),
   1817         num_tasks_processed_(0),
   1818         num_tasks_(num_tasks) {}
   1819 
   1820   virtual ~DummyTaskObserver() {}
   1821 
   1822   virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE {
   1823     num_tasks_started_++;
   1824     EXPECT_TRUE(pending_task.time_posted != TimeTicks());
   1825     EXPECT_LE(num_tasks_started_, num_tasks_);
   1826     EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1);
   1827   }
   1828 
   1829   virtual void DidProcessTask(const PendingTask& pending_task) OVERRIDE {
   1830     num_tasks_processed_++;
   1831     EXPECT_TRUE(pending_task.time_posted != TimeTicks());
   1832     EXPECT_LE(num_tasks_started_, num_tasks_);
   1833     EXPECT_EQ(num_tasks_started_, num_tasks_processed_);
   1834   }
   1835 
   1836   int num_tasks_started() const { return num_tasks_started_; }
   1837   int num_tasks_processed() const { return num_tasks_processed_; }
   1838 
   1839  private:
   1840   int num_tasks_started_;
   1841   int num_tasks_processed_;
   1842   const int num_tasks_;
   1843 
   1844   DISALLOW_COPY_AND_ASSIGN(DummyTaskObserver);
   1845 };
   1846 
   1847 TEST(MessageLoopTest, TaskObserver) {
   1848   const int kNumPosts = 6;
   1849   DummyTaskObserver observer(kNumPosts);
   1850 
   1851   MessageLoop loop;
   1852   loop.AddTaskObserver(&observer);
   1853   loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, kNumPosts));
   1854   loop.Run();
   1855   loop.RemoveTaskObserver(&observer);
   1856 
   1857   EXPECT_EQ(kNumPosts, observer.num_tasks_started());
   1858   EXPECT_EQ(kNumPosts, observer.num_tasks_processed());
   1859 }
   1860 
   1861 #if defined(OS_WIN)
   1862 TEST(MessageLoopTest, Dispatcher) {
   1863   // This test requires a UI loop
   1864   RunTest_Dispatcher(MessageLoop::TYPE_UI);
   1865 }
   1866 
   1867 TEST(MessageLoopTest, DispatcherWithMessageHook) {
   1868   // This test requires a UI loop
   1869   RunTest_DispatcherWithMessageHook(MessageLoop::TYPE_UI);
   1870 }
   1871 
   1872 TEST(MessageLoopTest, IOHandler) {
   1873   RunTest_IOHandler();
   1874 }
   1875 
   1876 TEST(MessageLoopTest, WaitForIO) {
   1877   RunTest_WaitForIO();
   1878 }
   1879 
   1880 TEST(MessageLoopTest, HighResolutionTimer) {
   1881   MessageLoop loop;
   1882 
   1883   const TimeDelta kFastTimer = TimeDelta::FromMilliseconds(5);
   1884   const TimeDelta kSlowTimer = TimeDelta::FromMilliseconds(100);
   1885 
   1886   EXPECT_FALSE(loop.IsHighResolutionTimerEnabledForTesting());
   1887 
   1888   // Post a fast task to enable the high resolution timers.
   1889   loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
   1890                        kFastTimer);
   1891   loop.Run();
   1892   EXPECT_TRUE(loop.IsHighResolutionTimerEnabledForTesting());
   1893 
   1894   // Post a slow task and verify high resolution timers
   1895   // are still enabled.
   1896   loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
   1897                        kSlowTimer);
   1898   loop.Run();
   1899   EXPECT_TRUE(loop.IsHighResolutionTimerEnabledForTesting());
   1900 
   1901   // Wait for a while so that high-resolution mode elapses.
   1902   PlatformThread::Sleep(TimeDelta::FromMilliseconds(
   1903       MessageLoop::kHighResolutionTimerModeLeaseTimeMs));
   1904 
   1905   // Post a slow task to disable the high resolution timers.
   1906   loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
   1907                        kSlowTimer);
   1908   loop.Run();
   1909   EXPECT_FALSE(loop.IsHighResolutionTimerEnabledForTesting());
   1910 }
   1911 
   1912 #endif  // defined(OS_WIN)
   1913 
   1914 #if defined(OS_POSIX) && !defined(OS_NACL)
   1915 
   1916 namespace {
   1917 
   1918 class QuitDelegate : public MessageLoopForIO::Watcher {
   1919  public:
   1920   virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
   1921     MessageLoop::current()->QuitWhenIdle();
   1922   }
   1923   virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
   1924     MessageLoop::current()->QuitWhenIdle();
   1925   }
   1926 };
   1927 
   1928 TEST(MessageLoopTest, FileDescriptorWatcherOutlivesMessageLoop) {
   1929   // Simulate a MessageLoop that dies before an FileDescriptorWatcher.
   1930   // This could happen when people use the Singleton pattern or atexit.
   1931 
   1932   // Create a file descriptor.  Doesn't need to be readable or writable,
   1933   // as we don't need to actually get any notifications.
   1934   // pipe() is just the easiest way to do it.
   1935   int pipefds[2];
   1936   int err = pipe(pipefds);
   1937   ASSERT_EQ(0, err);
   1938   int fd = pipefds[1];
   1939   {
   1940     // Arrange for controller to live longer than message loop.
   1941     MessageLoopForIO::FileDescriptorWatcher controller;
   1942     {
   1943       MessageLoopForIO message_loop;
   1944 
   1945       QuitDelegate delegate;
   1946       message_loop.WatchFileDescriptor(fd,
   1947           true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate);
   1948       // and don't run the message loop, just destroy it.
   1949     }
   1950   }
   1951   if (HANDLE_EINTR(close(pipefds[0])) < 0)
   1952     PLOG(ERROR) << "close";
   1953   if (HANDLE_EINTR(close(pipefds[1])) < 0)
   1954     PLOG(ERROR) << "close";
   1955 }
   1956 
   1957 TEST(MessageLoopTest, FileDescriptorWatcherDoubleStop) {
   1958   // Verify that it's ok to call StopWatchingFileDescriptor().
   1959   // (Errors only showed up in valgrind.)
   1960   int pipefds[2];
   1961   int err = pipe(pipefds);
   1962   ASSERT_EQ(0, err);
   1963   int fd = pipefds[1];
   1964   {
   1965     // Arrange for message loop to live longer than controller.
   1966     MessageLoopForIO message_loop;
   1967     {
   1968       MessageLoopForIO::FileDescriptorWatcher controller;
   1969 
   1970       QuitDelegate delegate;
   1971       message_loop.WatchFileDescriptor(fd,
   1972           true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate);
   1973       controller.StopWatchingFileDescriptor();
   1974     }
   1975   }
   1976   if (HANDLE_EINTR(close(pipefds[0])) < 0)
   1977     PLOG(ERROR) << "close";
   1978   if (HANDLE_EINTR(close(pipefds[1])) < 0)
   1979     PLOG(ERROR) << "close";
   1980 }
   1981 
   1982 }  // namespace
   1983 
   1984 #endif  // defined(OS_POSIX) && !defined(OS_NACL)
   1985 
   1986 namespace {
   1987 // Inject a test point for recording the destructor calls for Closure objects
   1988 // send to MessageLoop::PostTask(). It is awkward usage since we are trying to
   1989 // hook the actual destruction, which is not a common operation.
   1990 class DestructionObserverProbe :
   1991   public RefCounted<DestructionObserverProbe> {
   1992  public:
   1993   DestructionObserverProbe(bool* task_destroyed,
   1994                            bool* destruction_observer_called)
   1995       : task_destroyed_(task_destroyed),
   1996         destruction_observer_called_(destruction_observer_called) {
   1997   }
   1998   virtual void Run() {
   1999     // This task should never run.
   2000     ADD_FAILURE();
   2001   }
   2002  private:
   2003   friend class RefCounted<DestructionObserverProbe>;
   2004 
   2005   virtual ~DestructionObserverProbe() {
   2006     EXPECT_FALSE(*destruction_observer_called_);
   2007     *task_destroyed_ = true;
   2008   }
   2009 
   2010   bool* task_destroyed_;
   2011   bool* destruction_observer_called_;
   2012 };
   2013 
   2014 class MLDestructionObserver : public MessageLoop::DestructionObserver {
   2015  public:
   2016   MLDestructionObserver(bool* task_destroyed, bool* destruction_observer_called)
   2017       : task_destroyed_(task_destroyed),
   2018         destruction_observer_called_(destruction_observer_called),
   2019         task_destroyed_before_message_loop_(false) {
   2020   }
   2021   virtual void WillDestroyCurrentMessageLoop() OVERRIDE {
   2022     task_destroyed_before_message_loop_ = *task_destroyed_;
   2023     *destruction_observer_called_ = true;
   2024   }
   2025   bool task_destroyed_before_message_loop() const {
   2026     return task_destroyed_before_message_loop_;
   2027   }
   2028  private:
   2029   bool* task_destroyed_;
   2030   bool* destruction_observer_called_;
   2031   bool task_destroyed_before_message_loop_;
   2032 };
   2033 
   2034 }  // namespace
   2035 
   2036 TEST(MessageLoopTest, DestructionObserverTest) {
   2037   // Verify that the destruction observer gets called at the very end (after
   2038   // all the pending tasks have been destroyed).
   2039   MessageLoop* loop = new MessageLoop;
   2040   const TimeDelta kDelay = TimeDelta::FromMilliseconds(100);
   2041 
   2042   bool task_destroyed = false;
   2043   bool destruction_observer_called = false;
   2044 
   2045   MLDestructionObserver observer(&task_destroyed, &destruction_observer_called);
   2046   loop->AddDestructionObserver(&observer);
   2047   loop->PostDelayedTask(
   2048       FROM_HERE,
   2049       Bind(&DestructionObserverProbe::Run,
   2050                  new DestructionObserverProbe(&task_destroyed,
   2051                                               &destruction_observer_called)),
   2052       kDelay);
   2053   delete loop;
   2054   EXPECT_TRUE(observer.task_destroyed_before_message_loop());
   2055   // The task should have been destroyed when we deleted the loop.
   2056   EXPECT_TRUE(task_destroyed);
   2057   EXPECT_TRUE(destruction_observer_called);
   2058 }
   2059 
   2060 
   2061 // Verify that MessageLoop sets ThreadMainTaskRunner::current() and it
   2062 // posts tasks on that message loop.
   2063 TEST(MessageLoopTest, ThreadMainTaskRunner) {
   2064   MessageLoop loop;
   2065 
   2066   scoped_refptr<Foo> foo(new Foo());
   2067   std::string a("a");
   2068   ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, Bind(
   2069       &Foo::Test1ConstRef, foo.get(), a));
   2070 
   2071   // Post quit task;
   2072   MessageLoop::current()->PostTask(FROM_HERE, Bind(
   2073       &MessageLoop::Quit, Unretained(MessageLoop::current())));
   2074 
   2075   // Now kick things off
   2076   MessageLoop::current()->Run();
   2077 
   2078   EXPECT_EQ(foo->test_count(), 1);
   2079   EXPECT_EQ(foo->result(), "a");
   2080 }
   2081 
   2082 TEST(MessageLoopTest, IsType) {
   2083   MessageLoop loop(MessageLoop::TYPE_UI);
   2084   EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI));
   2085   EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO));
   2086   EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT));
   2087 }
   2088 
   2089 TEST(MessageLoopTest, RecursivePosts) {
   2090   // There was a bug in the MessagePumpGLib where posting tasks recursively
   2091   // caused the message loop to hang, due to the buffer of the internal pipe
   2092   // becoming full. Test all MessageLoop types to ensure this issue does not
   2093   // exist in other MessagePumps.
   2094 
   2095   // On Linux, the pipe buffer size is 64KiB by default. The bug caused one
   2096   // byte accumulated in the pipe per two posts, so we should repeat 128K
   2097   // times to reproduce the bug.
   2098   const int kNumTimes = 1 << 17;
   2099   RunTest_RecursivePosts(MessageLoop::TYPE_DEFAULT, kNumTimes);
   2100   RunTest_RecursivePosts(MessageLoop::TYPE_UI, kNumTimes);
   2101   RunTest_RecursivePosts(MessageLoop::TYPE_IO, kNumTimes);
   2102 }
   2103 
   2104 }  // namespace base
   2105