Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2008 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 "base/logging.h"
      6 #include "base/message_loop.h"
      7 #include "base/platform_thread.h"
      8 #include "base/ref_counted.h"
      9 #include "base/thread.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 #if defined(OS_WIN)
     13 #include "base/message_pump_win.h"
     14 #include "base/scoped_handle.h"
     15 #endif
     16 #if defined(OS_POSIX)
     17 #include "base/message_pump_libevent.h"
     18 #endif
     19 
     20 using base::Thread;
     21 using base::Time;
     22 using base::TimeDelta;
     23 
     24 // TODO(darin): Platform-specific MessageLoop tests should be grouped together
     25 // to avoid chopping this file up with so many #ifdefs.
     26 
     27 namespace {
     28 
     29 class MessageLoopTest : public testing::Test {};
     30 
     31 class Foo : public base::RefCounted<Foo> {
     32  public:
     33   Foo() : test_count_(0) {
     34   }
     35 
     36   void Test0() {
     37     ++test_count_;
     38   }
     39 
     40   void Test1ConstRef(const std::string& a) {
     41     ++test_count_;
     42     result_.append(a);
     43   }
     44 
     45   void Test1Ptr(std::string* a) {
     46     ++test_count_;
     47     result_.append(*a);
     48   }
     49 
     50   void Test1Int(int a) {
     51     test_count_ += a;
     52   }
     53 
     54   void Test2Ptr(std::string* a, std::string* b) {
     55     ++test_count_;
     56     result_.append(*a);
     57     result_.append(*b);
     58   }
     59 
     60   void Test2Mixed(const std::string& a, std::string* b) {
     61     ++test_count_;
     62     result_.append(a);
     63     result_.append(*b);
     64   }
     65 
     66   int test_count() const { return test_count_; }
     67   const std::string& result() const { return result_; }
     68 
     69  private:
     70   friend class base::RefCounted<Foo>;
     71 
     72   ~Foo() {}
     73 
     74   int test_count_;
     75   std::string result_;
     76 };
     77 
     78 class QuitMsgLoop : public base::RefCounted<QuitMsgLoop> {
     79  public:
     80   void QuitNow() {
     81     MessageLoop::current()->Quit();
     82   }
     83 
     84  private:
     85   friend class base::RefCounted<QuitMsgLoop>;
     86 
     87   ~QuitMsgLoop() {}
     88 };
     89 
     90 void RunTest_PostTask(MessageLoop::Type message_loop_type) {
     91   MessageLoop loop(message_loop_type);
     92 
     93   // Add tests to message loop
     94   scoped_refptr<Foo> foo = new Foo();
     95   std::string a("a"), b("b"), c("c"), d("d");
     96   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
     97       foo.get(), &Foo::Test0));
     98   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
     99     foo.get(), &Foo::Test1ConstRef, a));
    100   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    101       foo.get(), &Foo::Test1Ptr, &b));
    102   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    103       foo.get(), &Foo::Test1Int, 100));
    104   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    105       foo.get(), &Foo::Test2Ptr, &a, &c));
    106   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    107     foo.get(), &Foo::Test2Mixed, a, &d));
    108 
    109   // After all tests, post a message that will shut down the message loop
    110   scoped_refptr<QuitMsgLoop> quit = new QuitMsgLoop();
    111   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    112       quit.get(), &QuitMsgLoop::QuitNow));
    113 
    114   // Now kick things off
    115   MessageLoop::current()->Run();
    116 
    117   EXPECT_EQ(foo->test_count(), 105);
    118   EXPECT_EQ(foo->result(), "abacad");
    119 }
    120 
    121 void RunTest_PostTask_SEH(MessageLoop::Type message_loop_type) {
    122   MessageLoop loop(message_loop_type);
    123 
    124   // Add tests to message loop
    125   scoped_refptr<Foo> foo = new Foo();
    126   std::string a("a"), b("b"), c("c"), d("d");
    127   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    128       foo.get(), &Foo::Test0));
    129   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    130       foo.get(), &Foo::Test1ConstRef, a));
    131   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    132       foo.get(), &Foo::Test1Ptr, &b));
    133   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    134       foo.get(), &Foo::Test1Int, 100));
    135   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    136       foo.get(), &Foo::Test2Ptr, &a, &c));
    137   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    138       foo.get(), &Foo::Test2Mixed, a, &d));
    139 
    140   // After all tests, post a message that will shut down the message loop
    141   scoped_refptr<QuitMsgLoop> quit = new QuitMsgLoop();
    142   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
    143       quit.get(), &QuitMsgLoop::QuitNow));
    144 
    145   // Now kick things off with the SEH block active.
    146   MessageLoop::current()->set_exception_restoration(true);
    147   MessageLoop::current()->Run();
    148   MessageLoop::current()->set_exception_restoration(false);
    149 
    150   EXPECT_EQ(foo->test_count(), 105);
    151   EXPECT_EQ(foo->result(), "abacad");
    152 }
    153 
    154 // This class runs slowly to simulate a large amount of work being done.
    155 class SlowTask : public Task {
    156  public:
    157   SlowTask(int pause_ms, int* quit_counter)
    158       : pause_ms_(pause_ms), quit_counter_(quit_counter) {
    159   }
    160   virtual void Run() {
    161     PlatformThread::Sleep(pause_ms_);
    162     if (--(*quit_counter_) == 0)
    163       MessageLoop::current()->Quit();
    164   }
    165  private:
    166   int pause_ms_;
    167   int* quit_counter_;
    168 };
    169 
    170 // This class records the time when Run was called in a Time object, which is
    171 // useful for building a variety of MessageLoop tests.
    172 class RecordRunTimeTask : public SlowTask {
    173  public:
    174   RecordRunTimeTask(Time* run_time, int* quit_counter)
    175       : SlowTask(10, quit_counter), run_time_(run_time) {
    176   }
    177   virtual void Run() {
    178     *run_time_ = Time::Now();
    179     // Cause our Run function to take some time to execute.  As a result we can
    180     // count on subsequent RecordRunTimeTask objects running at a future time,
    181     // without worry about the resolution of our system clock being an issue.
    182     SlowTask::Run();
    183   }
    184  private:
    185   Time* run_time_;
    186 };
    187 
    188 void RunTest_PostDelayedTask_Basic(MessageLoop::Type message_loop_type) {
    189   MessageLoop loop(message_loop_type);
    190 
    191   // Test that PostDelayedTask results in a delayed task.
    192 
    193   const int kDelayMS = 100;
    194 
    195   int num_tasks = 1;
    196   Time run_time;
    197 
    198   loop.PostDelayedTask(
    199       FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), kDelayMS);
    200 
    201   Time time_before_run = Time::Now();
    202   loop.Run();
    203   Time time_after_run = Time::Now();
    204 
    205   EXPECT_EQ(0, num_tasks);
    206   EXPECT_LT(kDelayMS, (time_after_run - time_before_run).InMilliseconds());
    207 }
    208 
    209 void RunTest_PostDelayedTask_InDelayOrder(MessageLoop::Type message_loop_type) {
    210   MessageLoop loop(message_loop_type);
    211 
    212   // Test that two tasks with different delays run in the right order.
    213 
    214   int num_tasks = 2;
    215   Time run_time1, run_time2;
    216 
    217   loop.PostDelayedTask(
    218       FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), 200);
    219   // If we get a large pause in execution (due to a context switch) here, this
    220   // test could fail.
    221   loop.PostDelayedTask(
    222       FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 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(MessageLoop::Type message_loop_type) {
    231   MessageLoop loop(message_loop_type);
    232 
    233   // Test that two tasks with the same delay run in the order in which they
    234   // were posted.
    235   //
    236   // NOTE: This is actually an approximate test since the API only takes a
    237   // "delay" parameter, so we are not exactly simulating two tasks that get
    238   // posted at the exact same time.  It would be nice if the API allowed us to
    239   // specify the desired run time.
    240 
    241   const int kDelayMS = 100;
    242 
    243   int num_tasks = 2;
    244   Time run_time1, run_time2;
    245 
    246   loop.PostDelayedTask(
    247       FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), kDelayMS);
    248   loop.PostDelayedTask(
    249       FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), kDelayMS);
    250 
    251   loop.Run();
    252   EXPECT_EQ(0, num_tasks);
    253 
    254   EXPECT_TRUE(run_time1 < run_time2);
    255 }
    256 
    257 void RunTest_PostDelayedTask_InPostOrder_2(
    258     MessageLoop::Type message_loop_type) {
    259   MessageLoop loop(message_loop_type);
    260 
    261   // Test that a delayed task still runs after a normal tasks even if the
    262   // normal tasks take a long time to run.
    263 
    264   const int kPauseMS = 50;
    265 
    266   int num_tasks = 2;
    267   Time run_time;
    268 
    269   loop.PostTask(
    270       FROM_HERE, new SlowTask(kPauseMS, &num_tasks));
    271   loop.PostDelayedTask(
    272       FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), 10);
    273 
    274   Time time_before_run = Time::Now();
    275   loop.Run();
    276   Time time_after_run = Time::Now();
    277 
    278   EXPECT_EQ(0, num_tasks);
    279 
    280   EXPECT_LT(kPauseMS, (time_after_run - time_before_run).InMilliseconds());
    281 }
    282 
    283 void RunTest_PostDelayedTask_InPostOrder_3(
    284     MessageLoop::Type message_loop_type) {
    285   MessageLoop loop(message_loop_type);
    286 
    287   // Test that a delayed task still runs after a pile of normal tasks.  The key
    288   // difference between this test and the previous one is that here we return
    289   // the MessageLoop a lot so we give the MessageLoop plenty of opportunities
    290   // to maybe run the delayed task.  It should know not to do so until the
    291   // delayed task's delay has passed.
    292 
    293   int num_tasks = 11;
    294   Time run_time1, run_time2;
    295 
    296   // Clutter the ML with tasks.
    297   for (int i = 1; i < num_tasks; ++i)
    298     loop.PostTask(FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks));
    299 
    300   loop.PostDelayedTask(
    301       FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 1);
    302 
    303   loop.Run();
    304   EXPECT_EQ(0, num_tasks);
    305 
    306   EXPECT_TRUE(run_time2 > run_time1);
    307 }
    308 
    309 void RunTest_PostDelayedTask_SharedTimer(MessageLoop::Type message_loop_type) {
    310   MessageLoop loop(message_loop_type);
    311 
    312   // Test that the interval of the timer, used to run the next delayed task, is
    313   // set to a value corresponding to when the next delayed task should run.
    314 
    315   // By setting num_tasks to 1, we ensure that the first task to run causes the
    316   // run loop to exit.
    317   int num_tasks = 1;
    318   Time run_time1, run_time2;
    319 
    320   loop.PostDelayedTask(
    321       FROM_HERE, new RecordRunTimeTask(&run_time1, &num_tasks), 1000000);
    322   loop.PostDelayedTask(
    323       FROM_HERE, new RecordRunTimeTask(&run_time2, &num_tasks), 10);
    324 
    325   Time start_time = Time::Now();
    326 
    327   loop.Run();
    328   EXPECT_EQ(0, num_tasks);
    329 
    330   // Ensure that we ran in far less time than the slower timer.
    331   TimeDelta total_time = Time::Now() - start_time;
    332   EXPECT_GT(5000, total_time.InMilliseconds());
    333 
    334   // In case both timers somehow run at nearly the same time, sleep a little
    335   // and then run all pending to force them both to have run.  This is just
    336   // encouraging flakiness if there is any.
    337   PlatformThread::Sleep(100);
    338   loop.RunAllPending();
    339 
    340   EXPECT_TRUE(run_time1.is_null());
    341   EXPECT_FALSE(run_time2.is_null());
    342 }
    343 
    344 #if defined(OS_WIN)
    345 
    346 class SubPumpTask : public Task {
    347  public:
    348   virtual void Run() {
    349     MessageLoop::current()->SetNestableTasksAllowed(true);
    350     MSG msg;
    351     while (GetMessage(&msg, NULL, 0, 0)) {
    352       TranslateMessage(&msg);
    353       DispatchMessage(&msg);
    354     }
    355     MessageLoop::current()->Quit();
    356   }
    357 };
    358 
    359 class SubPumpQuitTask : public Task {
    360  public:
    361   SubPumpQuitTask() {
    362   }
    363   virtual void Run() {
    364     PostQuitMessage(0);
    365   }
    366 };
    367 
    368 void RunTest_PostDelayedTask_SharedTimer_SubPump() {
    369   MessageLoop loop(MessageLoop::TYPE_UI);
    370 
    371   // Test that the interval of the timer, used to run the next delayed task, is
    372   // set to a value corresponding to when the next delayed task should run.
    373 
    374   // By setting num_tasks to 1, we ensure that the first task to run causes the
    375   // run loop to exit.
    376   int num_tasks = 1;
    377   Time run_time;
    378 
    379   loop.PostTask(FROM_HERE, new SubPumpTask());
    380 
    381   // This very delayed task should never run.
    382   loop.PostDelayedTask(
    383       FROM_HERE, new RecordRunTimeTask(&run_time, &num_tasks), 1000000);
    384 
    385   // This slightly delayed task should run from within SubPumpTask::Run().
    386   loop.PostDelayedTask(
    387       FROM_HERE, new SubPumpQuitTask(), 10);
    388 
    389   Time start_time = Time::Now();
    390 
    391   loop.Run();
    392   EXPECT_EQ(1, num_tasks);
    393 
    394   // Ensure that we ran in far less time than the slower timer.
    395   TimeDelta total_time = Time::Now() - start_time;
    396   EXPECT_GT(5000, total_time.InMilliseconds());
    397 
    398   // In case both timers somehow run at nearly the same time, sleep a little
    399   // and then run all pending to force them both to have run.  This is just
    400   // encouraging flakiness if there is any.
    401   PlatformThread::Sleep(100);
    402   loop.RunAllPending();
    403 
    404   EXPECT_TRUE(run_time.is_null());
    405 }
    406 
    407 #endif  // defined(OS_WIN)
    408 
    409 class RecordDeletionTask : public Task {
    410  public:
    411   RecordDeletionTask(Task* post_on_delete, bool* was_deleted)
    412       : post_on_delete_(post_on_delete), was_deleted_(was_deleted) {
    413   }
    414   ~RecordDeletionTask() {
    415     *was_deleted_ = true;
    416     if (post_on_delete_)
    417       MessageLoop::current()->PostTask(FROM_HERE, post_on_delete_);
    418   }
    419   virtual void Run() {}
    420  private:
    421   Task* post_on_delete_;
    422   bool* was_deleted_;
    423 };
    424 
    425 void RunTest_EnsureTaskDeletion(MessageLoop::Type message_loop_type) {
    426   bool a_was_deleted = false;
    427   bool b_was_deleted = false;
    428   {
    429     MessageLoop loop(message_loop_type);
    430     loop.PostTask(
    431         FROM_HERE, new RecordDeletionTask(NULL, &a_was_deleted));
    432     loop.PostDelayedTask(
    433         FROM_HERE, new RecordDeletionTask(NULL, &b_was_deleted), 1000);
    434   }
    435   EXPECT_TRUE(a_was_deleted);
    436   EXPECT_TRUE(b_was_deleted);
    437 }
    438 
    439 void RunTest_EnsureTaskDeletion_Chain(MessageLoop::Type message_loop_type) {
    440   bool a_was_deleted = false;
    441   bool b_was_deleted = false;
    442   bool c_was_deleted = false;
    443   {
    444     MessageLoop loop(message_loop_type);
    445     RecordDeletionTask* a = new RecordDeletionTask(NULL, &a_was_deleted);
    446     RecordDeletionTask* b = new RecordDeletionTask(a, &b_was_deleted);
    447     RecordDeletionTask* c = new RecordDeletionTask(b, &c_was_deleted);
    448     loop.PostTask(FROM_HERE, c);
    449   }
    450   EXPECT_TRUE(a_was_deleted);
    451   EXPECT_TRUE(b_was_deleted);
    452   EXPECT_TRUE(c_was_deleted);
    453 }
    454 
    455 class NestingTest : public Task {
    456  public:
    457   explicit NestingTest(int* depth) : depth_(depth) {
    458   }
    459   void Run() {
    460     if (*depth_ > 0) {
    461       *depth_ -= 1;
    462       MessageLoop::current()->PostTask(FROM_HERE, new NestingTest(depth_));
    463 
    464       MessageLoop::current()->SetNestableTasksAllowed(true);
    465       MessageLoop::current()->Run();
    466     }
    467     MessageLoop::current()->Quit();
    468   }
    469  private:
    470   int* depth_;
    471 };
    472 
    473 #if defined(OS_WIN)
    474 
    475 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) {
    476   ADD_FAILURE() << "bad exception handler";
    477   ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode);
    478   return EXCEPTION_EXECUTE_HANDLER;
    479 }
    480 
    481 // This task throws an SEH exception: initially write to an invalid address.
    482 // If the right SEH filter is installed, it will fix the error.
    483 class CrasherTask : public Task {
    484  public:
    485   // Ctor. If trash_SEH_handler is true, the task will override the unhandled
    486   // exception handler with one sure to crash this test.
    487   explicit CrasherTask(bool trash_SEH_handler)
    488       : trash_SEH_handler_(trash_SEH_handler) {
    489   }
    490   void Run() {
    491     PlatformThread::Sleep(1);
    492     if (trash_SEH_handler_)
    493       ::SetUnhandledExceptionFilter(&BadExceptionHandler);
    494     // Generate a SEH fault. We do it in asm to make sure we know how to undo
    495     // the damage.
    496 
    497 #if defined(_M_IX86)
    498 
    499     __asm {
    500       mov eax, dword ptr [CrasherTask::bad_array_]
    501       mov byte ptr [eax], 66
    502     }
    503 
    504 #elif defined(_M_X64)
    505 
    506     bad_array_[0] = 66;
    507 
    508 #else
    509 #error "needs architecture support"
    510 #endif
    511 
    512     MessageLoop::current()->Quit();
    513   }
    514   // Points the bad array to a valid memory location.
    515   static void FixError() {
    516     bad_array_ = &valid_store_;
    517   }
    518 
    519  private:
    520   bool trash_SEH_handler_;
    521   static volatile char* bad_array_;
    522   static char valid_store_;
    523 };
    524 
    525 volatile char* CrasherTask::bad_array_ = 0;
    526 char CrasherTask::valid_store_ = 0;
    527 
    528 // This SEH filter fixes the problem and retries execution. Fixing requires
    529 // that the last instruction: mov eax, [CrasherTask::bad_array_] to be retried
    530 // so we move the instruction pointer 5 bytes back.
    531 LONG WINAPI HandleCrasherTaskException(EXCEPTION_POINTERS *ex_info) {
    532   if (ex_info->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
    533     return EXCEPTION_EXECUTE_HANDLER;
    534 
    535   CrasherTask::FixError();
    536 
    537 #if defined(_M_IX86)
    538 
    539   ex_info->ContextRecord->Eip -= 5;
    540 
    541 #elif defined(_M_X64)
    542 
    543   ex_info->ContextRecord->Rip -= 5;
    544 
    545 #endif
    546 
    547   return EXCEPTION_CONTINUE_EXECUTION;
    548 }
    549 
    550 void RunTest_Crasher(MessageLoop::Type message_loop_type) {
    551   MessageLoop loop(message_loop_type);
    552 
    553   if (::IsDebuggerPresent())
    554     return;
    555 
    556   LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter =
    557       ::SetUnhandledExceptionFilter(&HandleCrasherTaskException);
    558 
    559   MessageLoop::current()->PostTask(FROM_HERE, new CrasherTask(false));
    560   MessageLoop::current()->set_exception_restoration(true);
    561   MessageLoop::current()->Run();
    562   MessageLoop::current()->set_exception_restoration(false);
    563 
    564   ::SetUnhandledExceptionFilter(old_SEH_filter);
    565 }
    566 
    567 void RunTest_CrasherNasty(MessageLoop::Type message_loop_type) {
    568   MessageLoop loop(message_loop_type);
    569 
    570   if (::IsDebuggerPresent())
    571     return;
    572 
    573   LPTOP_LEVEL_EXCEPTION_FILTER old_SEH_filter =
    574       ::SetUnhandledExceptionFilter(&HandleCrasherTaskException);
    575 
    576   MessageLoop::current()->PostTask(FROM_HERE, new CrasherTask(true));
    577   MessageLoop::current()->set_exception_restoration(true);
    578   MessageLoop::current()->Run();
    579   MessageLoop::current()->set_exception_restoration(false);
    580 
    581   ::SetUnhandledExceptionFilter(old_SEH_filter);
    582 }
    583 
    584 #endif  // defined(OS_WIN)
    585 
    586 void RunTest_Nesting(MessageLoop::Type message_loop_type) {
    587   MessageLoop loop(message_loop_type);
    588 
    589   int depth = 100;
    590   MessageLoop::current()->PostTask(FROM_HERE, new NestingTest(&depth));
    591   MessageLoop::current()->Run();
    592   EXPECT_EQ(depth, 0);
    593 }
    594 
    595 const wchar_t* const kMessageBoxTitle = L"MessageLoop Unit Test";
    596 
    597 enum TaskType {
    598   MESSAGEBOX,
    599   ENDDIALOG,
    600   RECURSIVE,
    601   TIMEDMESSAGELOOP,
    602   QUITMESSAGELOOP,
    603   ORDERERD,
    604   PUMPS,
    605   SLEEP,
    606 };
    607 
    608 // Saves the order in which the tasks executed.
    609 struct TaskItem {
    610   TaskItem(TaskType t, int c, bool s)
    611       : type(t),
    612         cookie(c),
    613         start(s) {
    614   }
    615 
    616   TaskType type;
    617   int cookie;
    618   bool start;
    619 
    620   bool operator == (const TaskItem& other) const {
    621     return type == other.type && cookie == other.cookie && start == other.start;
    622   }
    623 };
    624 
    625 typedef std::vector<TaskItem> TaskList;
    626 
    627 std::ostream& operator <<(std::ostream& os, TaskType type) {
    628   switch (type) {
    629   case MESSAGEBOX:        os << "MESSAGEBOX"; break;
    630   case ENDDIALOG:         os << "ENDDIALOG"; break;
    631   case RECURSIVE:         os << "RECURSIVE"; break;
    632   case TIMEDMESSAGELOOP:  os << "TIMEDMESSAGELOOP"; break;
    633   case QUITMESSAGELOOP:   os << "QUITMESSAGELOOP"; break;
    634   case ORDERERD:          os << "ORDERERD"; break;
    635   case PUMPS:             os << "PUMPS"; break;
    636   case SLEEP:             os << "SLEEP"; break;
    637   default:
    638     NOTREACHED();
    639     os << "Unknown TaskType";
    640     break;
    641   }
    642   return os;
    643 }
    644 
    645 std::ostream& operator <<(std::ostream& os, const TaskItem& item) {
    646   if (item.start)
    647     return os << item.type << " " << item.cookie << " starts";
    648   else
    649     return os << item.type << " " << item.cookie << " ends";
    650 }
    651 
    652 // Saves the order the tasks ran.
    653 class OrderedTasks : public Task {
    654  public:
    655   OrderedTasks(TaskList* order, int cookie)
    656       : order_(order),
    657         type_(ORDERERD),
    658         cookie_(cookie) {
    659   }
    660   OrderedTasks(TaskList* order, TaskType type, int cookie)
    661       : order_(order),
    662         type_(type),
    663         cookie_(cookie) {
    664   }
    665 
    666   void RunStart() {
    667     TaskItem item(type_, cookie_, true);
    668     DLOG(INFO) << item;
    669     order_->push_back(item);
    670   }
    671   void RunEnd() {
    672     TaskItem item(type_, cookie_, false);
    673     DLOG(INFO) << item;
    674     order_->push_back(item);
    675   }
    676 
    677   virtual void Run() {
    678     RunStart();
    679     RunEnd();
    680   }
    681 
    682  protected:
    683   TaskList* order() const {
    684     return order_;
    685   }
    686 
    687   int cookie() const {
    688     return cookie_;
    689   }
    690 
    691  private:
    692   TaskList* order_;
    693   TaskType type_;
    694   int cookie_;
    695 };
    696 
    697 #if defined(OS_WIN)
    698 
    699 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes,
    700 // common controls (like OpenFile) and StartDoc printing function can cause
    701 // implicit message loops.
    702 class MessageBoxTask : public OrderedTasks {
    703  public:
    704   MessageBoxTask(TaskList* order, int cookie, bool is_reentrant)
    705       : OrderedTasks(order, MESSAGEBOX, cookie),
    706         is_reentrant_(is_reentrant) {
    707   }
    708 
    709   virtual void Run() {
    710     RunStart();
    711     if (is_reentrant_)
    712       MessageLoop::current()->SetNestableTasksAllowed(true);
    713     MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK);
    714     RunEnd();
    715   }
    716 
    717  private:
    718   bool is_reentrant_;
    719 };
    720 
    721 // Will end the MessageBox.
    722 class EndDialogTask : public OrderedTasks {
    723  public:
    724   EndDialogTask(TaskList* order, int cookie)
    725       : OrderedTasks(order, ENDDIALOG, cookie) {
    726   }
    727 
    728   virtual void Run() {
    729     RunStart();
    730     HWND window = GetActiveWindow();
    731     if (window != NULL) {
    732       EXPECT_NE(EndDialog(window, IDCONTINUE), 0);
    733       // Cheap way to signal that the window wasn't found if RunEnd() isn't
    734       // called.
    735       RunEnd();
    736     }
    737   }
    738 };
    739 
    740 #endif  // defined(OS_WIN)
    741 
    742 class RecursiveTask : public OrderedTasks {
    743  public:
    744   RecursiveTask(int depth, TaskList* order, int cookie, bool is_reentrant)
    745       : OrderedTasks(order, RECURSIVE, cookie),
    746         depth_(depth),
    747         is_reentrant_(is_reentrant) {
    748   }
    749 
    750   virtual void Run() {
    751     RunStart();
    752     if (depth_ > 0) {
    753       if (is_reentrant_)
    754         MessageLoop::current()->SetNestableTasksAllowed(true);
    755       MessageLoop::current()->PostTask(FROM_HERE,
    756           new RecursiveTask(depth_ - 1, order(), cookie(), is_reentrant_));
    757     }
    758     RunEnd();
    759   }
    760 
    761  private:
    762   int depth_;
    763   bool is_reentrant_;
    764 };
    765 
    766 class QuitTask : public OrderedTasks {
    767  public:
    768   QuitTask(TaskList* order, int cookie)
    769       : OrderedTasks(order, QUITMESSAGELOOP, cookie) {
    770   }
    771 
    772   virtual void Run() {
    773     RunStart();
    774     MessageLoop::current()->Quit();
    775     RunEnd();
    776   }
    777 };
    778 
    779 class SleepTask : public OrderedTasks {
    780  public:
    781   SleepTask(TaskList* order, int cookie, int ms)
    782       : OrderedTasks(order, SLEEP, cookie), ms_(ms) {
    783   }
    784 
    785   virtual void Run() {
    786     RunStart();
    787     PlatformThread::Sleep(ms_);
    788     RunEnd();
    789   }
    790 
    791  private:
    792   int ms_;
    793 };
    794 
    795 #if defined(OS_WIN)
    796 
    797 class Recursive2Tasks : public Task {
    798  public:
    799   Recursive2Tasks(MessageLoop* target,
    800                   HANDLE event,
    801                   bool expect_window,
    802                   TaskList* order,
    803                   bool is_reentrant)
    804       : target_(target),
    805         event_(event),
    806         expect_window_(expect_window),
    807         order_(order),
    808         is_reentrant_(is_reentrant) {
    809   }
    810 
    811   virtual void Run() {
    812     target_->PostTask(FROM_HERE,
    813                       new RecursiveTask(2, order_, 1, is_reentrant_));
    814     target_->PostTask(FROM_HERE,
    815                       new MessageBoxTask(order_, 2, is_reentrant_));
    816     target_->PostTask(FROM_HERE,
    817                       new RecursiveTask(2, order_, 3, is_reentrant_));
    818     // The trick here is that for recursive task processing, this task will be
    819     // ran _inside_ the MessageBox message loop, dismissing the MessageBox
    820     // without a chance.
    821     // For non-recursive task processing, this will be executed _after_ the
    822     // MessageBox will have been dismissed by the code below, where
    823     // expect_window_ is true.
    824     target_->PostTask(FROM_HERE, new EndDialogTask(order_, 4));
    825     target_->PostTask(FROM_HERE, new QuitTask(order_, 5));
    826 
    827     // Enforce that every tasks are sent before starting to run the main thread
    828     // message loop.
    829     ASSERT_TRUE(SetEvent(event_));
    830 
    831     // Poll for the MessageBox. Don't do this at home! At the speed we do it,
    832     // you will never realize one MessageBox was shown.
    833     for (; expect_window_;) {
    834       HWND window = FindWindow(L"#32770", kMessageBoxTitle);
    835       if (window) {
    836         // Dismiss it.
    837         for (;;) {
    838           HWND button = FindWindowEx(window, NULL, L"Button", NULL);
    839           if (button != NULL) {
    840             EXPECT_TRUE(0 == SendMessage(button, WM_LBUTTONDOWN, 0, 0));
    841             EXPECT_TRUE(0 == SendMessage(button, WM_LBUTTONUP, 0, 0));
    842             break;
    843           }
    844         }
    845         break;
    846       }
    847     }
    848   }
    849 
    850  private:
    851   MessageLoop* target_;
    852   HANDLE event_;
    853   TaskList* order_;
    854   bool expect_window_;
    855   bool is_reentrant_;
    856 };
    857 
    858 #endif  // defined(OS_WIN)
    859 
    860 void RunTest_RecursiveDenial1(MessageLoop::Type message_loop_type) {
    861   MessageLoop loop(message_loop_type);
    862 
    863   EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed());
    864   TaskList order;
    865   MessageLoop::current()->PostTask(FROM_HERE,
    866                                    new RecursiveTask(2, &order, 1, false));
    867   MessageLoop::current()->PostTask(FROM_HERE,
    868                                    new RecursiveTask(2, &order, 2, false));
    869   MessageLoop::current()->PostTask(FROM_HERE, new QuitTask(&order, 3));
    870 
    871   MessageLoop::current()->Run();
    872 
    873   // FIFO order.
    874   ASSERT_EQ(14U, order.size());
    875   EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true));
    876   EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false));
    877   EXPECT_EQ(order[ 2], TaskItem(RECURSIVE, 2, true));
    878   EXPECT_EQ(order[ 3], TaskItem(RECURSIVE, 2, false));
    879   EXPECT_EQ(order[ 4], TaskItem(QUITMESSAGELOOP, 3, true));
    880   EXPECT_EQ(order[ 5], TaskItem(QUITMESSAGELOOP, 3, false));
    881   EXPECT_EQ(order[ 6], TaskItem(RECURSIVE, 1, true));
    882   EXPECT_EQ(order[ 7], TaskItem(RECURSIVE, 1, false));
    883   EXPECT_EQ(order[ 8], TaskItem(RECURSIVE, 2, true));
    884   EXPECT_EQ(order[ 9], TaskItem(RECURSIVE, 2, false));
    885   EXPECT_EQ(order[10], TaskItem(RECURSIVE, 1, true));
    886   EXPECT_EQ(order[11], TaskItem(RECURSIVE, 1, false));
    887   EXPECT_EQ(order[12], TaskItem(RECURSIVE, 2, true));
    888   EXPECT_EQ(order[13], TaskItem(RECURSIVE, 2, false));
    889 }
    890 
    891 void RunTest_RecursiveSupport1(MessageLoop::Type message_loop_type) {
    892   MessageLoop loop(message_loop_type);
    893 
    894   TaskList order;
    895   MessageLoop::current()->PostTask(FROM_HERE,
    896                                    new RecursiveTask(2, &order, 1, true));
    897   MessageLoop::current()->PostTask(FROM_HERE,
    898                                    new RecursiveTask(2, &order, 2, true));
    899   MessageLoop::current()->PostTask(FROM_HERE,
    900                                    new QuitTask(&order, 3));
    901 
    902   MessageLoop::current()->Run();
    903 
    904   // FIFO order.
    905   ASSERT_EQ(14U, order.size());
    906   EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true));
    907   EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false));
    908   EXPECT_EQ(order[ 2], TaskItem(RECURSIVE, 2, true));
    909   EXPECT_EQ(order[ 3], TaskItem(RECURSIVE, 2, false));
    910   EXPECT_EQ(order[ 4], TaskItem(QUITMESSAGELOOP, 3, true));
    911   EXPECT_EQ(order[ 5], TaskItem(QUITMESSAGELOOP, 3, false));
    912   EXPECT_EQ(order[ 6], TaskItem(RECURSIVE, 1, true));
    913   EXPECT_EQ(order[ 7], TaskItem(RECURSIVE, 1, false));
    914   EXPECT_EQ(order[ 8], TaskItem(RECURSIVE, 2, true));
    915   EXPECT_EQ(order[ 9], TaskItem(RECURSIVE, 2, false));
    916   EXPECT_EQ(order[10], TaskItem(RECURSIVE, 1, true));
    917   EXPECT_EQ(order[11], TaskItem(RECURSIVE, 1, false));
    918   EXPECT_EQ(order[12], TaskItem(RECURSIVE, 2, true));
    919   EXPECT_EQ(order[13], TaskItem(RECURSIVE, 2, false));
    920 }
    921 
    922 #if defined(OS_WIN)
    923 // TODO(darin): These tests need to be ported since they test critical
    924 // message loop functionality.
    925 
    926 // A side effect of this test is the generation a beep. Sorry.
    927 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) {
    928   MessageLoop loop(message_loop_type);
    929 
    930   Thread worker("RecursiveDenial2_worker");
    931   Thread::Options options;
    932   options.message_loop_type = message_loop_type;
    933   ASSERT_EQ(true, worker.StartWithOptions(options));
    934   TaskList order;
    935   ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
    936   worker.message_loop()->PostTask(FROM_HERE,
    937                                   new Recursive2Tasks(MessageLoop::current(),
    938                                                       event,
    939                                                       true,
    940                                                       &order,
    941                                                       false));
    942   // Let the other thread execute.
    943   WaitForSingleObject(event, INFINITE);
    944   MessageLoop::current()->Run();
    945 
    946   ASSERT_EQ(order.size(), 17);
    947   EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true));
    948   EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false));
    949   EXPECT_EQ(order[ 2], TaskItem(MESSAGEBOX, 2, true));
    950   EXPECT_EQ(order[ 3], TaskItem(MESSAGEBOX, 2, false));
    951   EXPECT_EQ(order[ 4], TaskItem(RECURSIVE, 3, true));
    952   EXPECT_EQ(order[ 5], TaskItem(RECURSIVE, 3, false));
    953   // When EndDialogTask is processed, the window is already dismissed, hence no
    954   // "end" entry.
    955   EXPECT_EQ(order[ 6], TaskItem(ENDDIALOG, 4, true));
    956   EXPECT_EQ(order[ 7], TaskItem(QUITMESSAGELOOP, 5, true));
    957   EXPECT_EQ(order[ 8], TaskItem(QUITMESSAGELOOP, 5, false));
    958   EXPECT_EQ(order[ 9], TaskItem(RECURSIVE, 1, true));
    959   EXPECT_EQ(order[10], TaskItem(RECURSIVE, 1, false));
    960   EXPECT_EQ(order[11], TaskItem(RECURSIVE, 3, true));
    961   EXPECT_EQ(order[12], TaskItem(RECURSIVE, 3, false));
    962   EXPECT_EQ(order[13], TaskItem(RECURSIVE, 1, true));
    963   EXPECT_EQ(order[14], TaskItem(RECURSIVE, 1, false));
    964   EXPECT_EQ(order[15], TaskItem(RECURSIVE, 3, true));
    965   EXPECT_EQ(order[16], TaskItem(RECURSIVE, 3, false));
    966 }
    967 
    968 // A side effect of this test is the generation a beep. Sorry.  This test also
    969 // needs to process windows messages on the current thread.
    970 void RunTest_RecursiveSupport2(MessageLoop::Type message_loop_type) {
    971   MessageLoop loop(message_loop_type);
    972 
    973   Thread worker("RecursiveSupport2_worker");
    974   Thread::Options options;
    975   options.message_loop_type = message_loop_type;
    976   ASSERT_EQ(true, worker.StartWithOptions(options));
    977   TaskList order;
    978   ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL));
    979   worker.message_loop()->PostTask(FROM_HERE,
    980                                   new Recursive2Tasks(MessageLoop::current(),
    981                                                       event,
    982                                                       false,
    983                                                       &order,
    984                                                       true));
    985   // Let the other thread execute.
    986   WaitForSingleObject(event, INFINITE);
    987   MessageLoop::current()->Run();
    988 
    989   ASSERT_EQ(order.size(), 18);
    990   EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true));
    991   EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false));
    992   EXPECT_EQ(order[ 2], TaskItem(MESSAGEBOX, 2, true));
    993   // Note that this executes in the MessageBox modal loop.
    994   EXPECT_EQ(order[ 3], TaskItem(RECURSIVE, 3, true));
    995   EXPECT_EQ(order[ 4], TaskItem(RECURSIVE, 3, false));
    996   EXPECT_EQ(order[ 5], TaskItem(ENDDIALOG, 4, true));
    997   EXPECT_EQ(order[ 6], TaskItem(ENDDIALOG, 4, false));
    998   EXPECT_EQ(order[ 7], TaskItem(MESSAGEBOX, 2, false));
    999   /* The order can subtly change here. The reason is that when RecursiveTask(1)
   1000      is called in the main thread, if it is faster than getting to the
   1001      PostTask(FROM_HERE, QuitTask) execution, the order of task execution can
   1002      change. We don't care anyway that the order isn't correct.
   1003   EXPECT_EQ(order[ 8], TaskItem(QUITMESSAGELOOP, 5, true));
   1004   EXPECT_EQ(order[ 9], TaskItem(QUITMESSAGELOOP, 5, false));
   1005   EXPECT_EQ(order[10], TaskItem(RECURSIVE, 1, true));
   1006   EXPECT_EQ(order[11], TaskItem(RECURSIVE, 1, false));
   1007   */
   1008   EXPECT_EQ(order[12], TaskItem(RECURSIVE, 3, true));
   1009   EXPECT_EQ(order[13], TaskItem(RECURSIVE, 3, false));
   1010   EXPECT_EQ(order[14], TaskItem(RECURSIVE, 1, true));
   1011   EXPECT_EQ(order[15], TaskItem(RECURSIVE, 1, false));
   1012   EXPECT_EQ(order[16], TaskItem(RECURSIVE, 3, true));
   1013   EXPECT_EQ(order[17], TaskItem(RECURSIVE, 3, false));
   1014 }
   1015 
   1016 #endif  // defined(OS_WIN)
   1017 
   1018 class TaskThatPumps : public OrderedTasks {
   1019  public:
   1020   TaskThatPumps(TaskList* order, int cookie)
   1021       : OrderedTasks(order, PUMPS, cookie) {
   1022   }
   1023 
   1024   virtual void Run() {
   1025     RunStart();
   1026     bool old_state = MessageLoop::current()->NestableTasksAllowed();
   1027     MessageLoop::current()->SetNestableTasksAllowed(true);
   1028     MessageLoop::current()->RunAllPending();
   1029     MessageLoop::current()->SetNestableTasksAllowed(old_state);
   1030     RunEnd();
   1031   }
   1032 };
   1033 
   1034 // Tests that non nestable tasks run in FIFO if there are no nested loops.
   1035 void RunTest_NonNestableWithNoNesting(MessageLoop::Type message_loop_type) {
   1036   MessageLoop loop(message_loop_type);
   1037 
   1038   TaskList order;
   1039 
   1040   Task* task = new OrderedTasks(&order, 1);
   1041   MessageLoop::current()->PostNonNestableTask(FROM_HERE, task);
   1042   MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 2));
   1043   MessageLoop::current()->PostTask(FROM_HERE, new QuitTask(&order, 3));
   1044   MessageLoop::current()->Run();
   1045 
   1046   // FIFO order.
   1047   ASSERT_EQ(6U, order.size());
   1048   EXPECT_EQ(order[ 0], TaskItem(ORDERERD, 1, true));
   1049   EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 1, false));
   1050   EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 2, true));
   1051   EXPECT_EQ(order[ 3], TaskItem(ORDERERD, 2, false));
   1052   EXPECT_EQ(order[ 4], TaskItem(QUITMESSAGELOOP, 3, true));
   1053   EXPECT_EQ(order[ 5], TaskItem(QUITMESSAGELOOP, 3, false));
   1054 }
   1055 
   1056 // Tests that non nestable tasks don't run when there's code in the call stack.
   1057 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type,
   1058                                      bool use_delayed) {
   1059   MessageLoop loop(message_loop_type);
   1060 
   1061   TaskList order;
   1062 
   1063   MessageLoop::current()->PostTask(FROM_HERE,
   1064                                    new TaskThatPumps(&order, 1));
   1065   Task* task = new OrderedTasks(&order, 2);
   1066   if (use_delayed) {
   1067     MessageLoop::current()->PostNonNestableDelayedTask(FROM_HERE, task, 1);
   1068   } else {
   1069     MessageLoop::current()->PostNonNestableTask(FROM_HERE, task);
   1070   }
   1071   MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 3));
   1072   MessageLoop::current()->PostTask(FROM_HERE, new SleepTask(&order, 4, 50));
   1073   MessageLoop::current()->PostTask(FROM_HERE, new OrderedTasks(&order, 5));
   1074   Task* non_nestable_quit = new QuitTask(&order, 6);
   1075   if (use_delayed) {
   1076     MessageLoop::current()->PostNonNestableDelayedTask(FROM_HERE,
   1077                                                        non_nestable_quit,
   1078                                                        2);
   1079   } else {
   1080     MessageLoop::current()->PostNonNestableTask(FROM_HERE, non_nestable_quit);
   1081   }
   1082 
   1083   MessageLoop::current()->Run();
   1084 
   1085   // FIFO order.
   1086   ASSERT_EQ(12U, order.size());
   1087   EXPECT_EQ(order[ 0], TaskItem(PUMPS, 1, true));
   1088   EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 3, true));
   1089   EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 3, false));
   1090   EXPECT_EQ(order[ 3], TaskItem(SLEEP, 4, true));
   1091   EXPECT_EQ(order[ 4], TaskItem(SLEEP, 4, false));
   1092   EXPECT_EQ(order[ 5], TaskItem(ORDERERD, 5, true));
   1093   EXPECT_EQ(order[ 6], TaskItem(ORDERERD, 5, false));
   1094   EXPECT_EQ(order[ 7], TaskItem(PUMPS, 1, false));
   1095   EXPECT_EQ(order[ 8], TaskItem(ORDERERD, 2, true));
   1096   EXPECT_EQ(order[ 9], TaskItem(ORDERERD, 2, false));
   1097   EXPECT_EQ(order[10], TaskItem(QUITMESSAGELOOP, 6, true));
   1098   EXPECT_EQ(order[11], TaskItem(QUITMESSAGELOOP, 6, false));
   1099 }
   1100 
   1101 #if defined(OS_WIN)
   1102 
   1103 class DispatcherImpl : public MessageLoopForUI::Dispatcher {
   1104  public:
   1105   DispatcherImpl() : dispatch_count_(0) {}
   1106 
   1107   virtual bool Dispatch(const MSG& msg) {
   1108     ::TranslateMessage(&msg);
   1109     ::DispatchMessage(&msg);
   1110     // Do not count WM_TIMER since it is not what we post and it will cause
   1111     // flakiness.
   1112     if (msg.message != WM_TIMER)
   1113       ++dispatch_count_;
   1114     // We treat WM_LBUTTONUP as the last message.
   1115     return msg.message != WM_LBUTTONUP;
   1116   }
   1117 
   1118   int dispatch_count_;
   1119 };
   1120 
   1121 void RunTest_Dispatcher(MessageLoop::Type message_loop_type) {
   1122   MessageLoop loop(message_loop_type);
   1123 
   1124   class MyTask : public Task {
   1125   public:
   1126     virtual void Run() {
   1127       PostMessage(NULL, WM_LBUTTONDOWN, 0, 0);
   1128       PostMessage(NULL, WM_LBUTTONUP, 'A', 0);
   1129     }
   1130   };
   1131   Task* task = new MyTask();
   1132   MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 100);
   1133   DispatcherImpl dispatcher;
   1134   MessageLoopForUI::current()->Run(&dispatcher);
   1135   ASSERT_EQ(2, dispatcher.dispatch_count_);
   1136 }
   1137 
   1138 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) {
   1139   if (code == base::MessagePumpForUI::kMessageFilterCode) {
   1140     MSG* msg = reinterpret_cast<MSG*>(lparam);
   1141     if (msg->message == WM_LBUTTONDOWN)
   1142       return TRUE;
   1143   }
   1144   return FALSE;
   1145 }
   1146 
   1147 void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) {
   1148   MessageLoop loop(message_loop_type);
   1149 
   1150   class MyTask : public Task {
   1151   public:
   1152     virtual void Run() {
   1153       PostMessage(NULL, WM_LBUTTONDOWN, 0, 0);
   1154       PostMessage(NULL, WM_LBUTTONUP, 'A', 0);
   1155     }
   1156   };
   1157   Task* task = new MyTask();
   1158   MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 100);
   1159   HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER,
   1160                                     MsgFilterProc,
   1161                                     NULL,
   1162                                     GetCurrentThreadId());
   1163   DispatcherImpl dispatcher;
   1164   MessageLoopForUI::current()->Run(&dispatcher);
   1165   ASSERT_EQ(1, dispatcher.dispatch_count_);
   1166   UnhookWindowsHookEx(msg_hook);
   1167 }
   1168 
   1169 class TestIOHandler : public MessageLoopForIO::IOHandler {
   1170  public:
   1171   TestIOHandler(const wchar_t* name, HANDLE signal, bool wait);
   1172 
   1173   virtual void OnIOCompleted(MessageLoopForIO::IOContext* context,
   1174                              DWORD bytes_transfered, DWORD error);
   1175 
   1176   void Init();
   1177   void WaitForIO();
   1178   OVERLAPPED* context() { return &context_.overlapped; }
   1179   DWORD size() { return sizeof(buffer_); }
   1180 
   1181  private:
   1182   char buffer_[48];
   1183   MessageLoopForIO::IOContext context_;
   1184   HANDLE signal_;
   1185   ScopedHandle file_;
   1186   bool wait_;
   1187 };
   1188 
   1189 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait)
   1190     : signal_(signal), wait_(wait) {
   1191   memset(buffer_, 0, sizeof(buffer_));
   1192   memset(&context_, 0, sizeof(context_));
   1193   context_.handler = this;
   1194 
   1195   file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
   1196                        FILE_FLAG_OVERLAPPED, NULL));
   1197   EXPECT_TRUE(file_.IsValid());
   1198 }
   1199 
   1200 void TestIOHandler::Init() {
   1201   MessageLoopForIO::current()->RegisterIOHandler(file_, this);
   1202 
   1203   DWORD read;
   1204   EXPECT_FALSE(ReadFile(file_, buffer_, size(), &read, context()));
   1205   EXPECT_EQ(ERROR_IO_PENDING, GetLastError());
   1206   if (wait_)
   1207     WaitForIO();
   1208 }
   1209 
   1210 void TestIOHandler::OnIOCompleted(MessageLoopForIO::IOContext* context,
   1211                                   DWORD bytes_transfered, DWORD error) {
   1212   ASSERT_TRUE(context == &context_);
   1213   ASSERT_TRUE(SetEvent(signal_));
   1214 }
   1215 
   1216 void TestIOHandler::WaitForIO() {
   1217   EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this));
   1218   EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this));
   1219 }
   1220 
   1221 class IOHandlerTask : public Task {
   1222  public:
   1223   explicit IOHandlerTask(TestIOHandler* handler) : handler_(handler) {}
   1224   virtual void Run() {
   1225     handler_->Init();
   1226   }
   1227 
   1228  private:
   1229   TestIOHandler* handler_;
   1230 };
   1231 
   1232 void RunTest_IOHandler() {
   1233   ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL));
   1234   ASSERT_TRUE(callback_called.IsValid());
   1235 
   1236   const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe";
   1237   ScopedHandle server(CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1,
   1238                                       0, 0, 0, NULL));
   1239   ASSERT_TRUE(server.IsValid());
   1240 
   1241   Thread thread("IOHandler test");
   1242   Thread::Options options;
   1243   options.message_loop_type = MessageLoop::TYPE_IO;
   1244   ASSERT_TRUE(thread.StartWithOptions(options));
   1245 
   1246   MessageLoop* thread_loop = thread.message_loop();
   1247   ASSERT_TRUE(NULL != thread_loop);
   1248 
   1249   TestIOHandler handler(kPipeName, callback_called, false);
   1250   IOHandlerTask* task = new IOHandlerTask(&handler);
   1251   thread_loop->PostTask(FROM_HERE, task);
   1252   Sleep(100);  // Make sure the thread runs and sleeps for lack of work.
   1253 
   1254   const char buffer[] = "Hello there!";
   1255   DWORD written;
   1256   EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL));
   1257 
   1258   DWORD result = WaitForSingleObject(callback_called, 1000);
   1259   EXPECT_EQ(WAIT_OBJECT_0, result);
   1260 
   1261   thread.Stop();
   1262 }
   1263 
   1264 void RunTest_WaitForIO() {
   1265   ScopedHandle callback1_called(CreateEvent(NULL, TRUE, FALSE, NULL));
   1266   ScopedHandle callback2_called(CreateEvent(NULL, TRUE, FALSE, NULL));
   1267   ASSERT_TRUE(callback1_called.IsValid());
   1268   ASSERT_TRUE(callback2_called.IsValid());
   1269 
   1270   const wchar_t* kPipeName1 = L"\\\\.\\pipe\\iohandler_pipe1";
   1271   const wchar_t* kPipeName2 = L"\\\\.\\pipe\\iohandler_pipe2";
   1272   ScopedHandle server1(CreateNamedPipe(kPipeName1, PIPE_ACCESS_OUTBOUND, 0, 1,
   1273                                        0, 0, 0, NULL));
   1274   ScopedHandle server2(CreateNamedPipe(kPipeName2, PIPE_ACCESS_OUTBOUND, 0, 1,
   1275                                        0, 0, 0, NULL));
   1276   ASSERT_TRUE(server1.IsValid());
   1277   ASSERT_TRUE(server2.IsValid());
   1278 
   1279   Thread thread("IOHandler test");
   1280   Thread::Options options;
   1281   options.message_loop_type = MessageLoop::TYPE_IO;
   1282   ASSERT_TRUE(thread.StartWithOptions(options));
   1283 
   1284   MessageLoop* thread_loop = thread.message_loop();
   1285   ASSERT_TRUE(NULL != thread_loop);
   1286 
   1287   TestIOHandler handler1(kPipeName1, callback1_called, false);
   1288   TestIOHandler handler2(kPipeName2, callback2_called, true);
   1289   IOHandlerTask* task1 = new IOHandlerTask(&handler1);
   1290   IOHandlerTask* task2 = new IOHandlerTask(&handler2);
   1291   thread_loop->PostTask(FROM_HERE, task1);
   1292   Sleep(100);  // Make sure the thread runs and sleeps for lack of work.
   1293   thread_loop->PostTask(FROM_HERE, task2);
   1294   Sleep(100);
   1295 
   1296   // At this time handler1 is waiting to be called, and the thread is waiting
   1297   // on the Init method of handler2, filtering only handler2 callbacks.
   1298 
   1299   const char buffer[] = "Hello there!";
   1300   DWORD written;
   1301   EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL));
   1302   Sleep(200);
   1303   EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) <<
   1304       "handler1 has not been called";
   1305 
   1306   EXPECT_TRUE(WriteFile(server2, buffer, sizeof(buffer), &written, NULL));
   1307 
   1308   HANDLE objects[2] = { callback1_called.Get(), callback2_called.Get() };
   1309   DWORD result = WaitForMultipleObjects(2, objects, TRUE, 1000);
   1310   EXPECT_EQ(WAIT_OBJECT_0, result);
   1311 
   1312   thread.Stop();
   1313 }
   1314 
   1315 #endif  // defined(OS_WIN)
   1316 
   1317 }  // namespace
   1318 
   1319 //-----------------------------------------------------------------------------
   1320 // Each test is run against each type of MessageLoop.  That way we are sure
   1321 // that message loops work properly in all configurations.  Of course, in some
   1322 // cases, a unit test may only be for a particular type of loop.
   1323 
   1324 TEST(MessageLoopTest, PostTask) {
   1325   RunTest_PostTask(MessageLoop::TYPE_DEFAULT);
   1326   RunTest_PostTask(MessageLoop::TYPE_UI);
   1327   RunTest_PostTask(MessageLoop::TYPE_IO);
   1328 }
   1329 
   1330 TEST(MessageLoopTest, PostTask_SEH) {
   1331   RunTest_PostTask_SEH(MessageLoop::TYPE_DEFAULT);
   1332   RunTest_PostTask_SEH(MessageLoop::TYPE_UI);
   1333   RunTest_PostTask_SEH(MessageLoop::TYPE_IO);
   1334 }
   1335 
   1336 TEST(MessageLoopTest, PostDelayedTask_Basic) {
   1337   RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_DEFAULT);
   1338   RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_UI);
   1339   RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_IO);
   1340 }
   1341 
   1342 TEST(MessageLoopTest, PostDelayedTask_InDelayOrder) {
   1343   RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_DEFAULT);
   1344   RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_UI);
   1345   RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_IO);
   1346 }
   1347 
   1348 TEST(MessageLoopTest, PostDelayedTask_InPostOrder) {
   1349   RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_DEFAULT);
   1350   RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_UI);
   1351   RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_IO);
   1352 }
   1353 
   1354 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_2) {
   1355   RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_DEFAULT);
   1356   RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_UI);
   1357   RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_IO);
   1358 }
   1359 
   1360 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_3) {
   1361   RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_DEFAULT);
   1362   RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_UI);
   1363   RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_IO);
   1364 }
   1365 
   1366 TEST(MessageLoopTest, PostDelayedTask_SharedTimer) {
   1367   RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_DEFAULT);
   1368   RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_UI);
   1369   RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_IO);
   1370 }
   1371 
   1372 #if defined(OS_WIN)
   1373 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) {
   1374   RunTest_PostDelayedTask_SharedTimer_SubPump();
   1375 }
   1376 #endif
   1377 
   1378 // TODO(darin): re-enable these tests once MessageLoop supports them again.
   1379 #if 0
   1380 TEST(MessageLoopTest, EnsureTaskDeletion) {
   1381   RunTest_EnsureTaskDeletion(MessageLoop::TYPE_DEFAULT);
   1382   RunTest_EnsureTaskDeletion(MessageLoop::TYPE_UI);
   1383   RunTest_EnsureTaskDeletion(MessageLoop::TYPE_IO);
   1384 }
   1385 
   1386 TEST(MessageLoopTest, EnsureTaskDeletion_Chain) {
   1387   RunTest_EnsureTaskDeletion_Chain(MessageLoop::TYPE_DEFAULT);
   1388   RunTest_EnsureTaskDeletion_Chain(MessageLoop::TYPE_UI);
   1389   RunTest_EnsureTaskDeletion_Chain(MessageLoop::TYPE_IO);
   1390 }
   1391 #endif
   1392 
   1393 #if defined(OS_WIN)
   1394 TEST(MessageLoopTest, Crasher) {
   1395   RunTest_Crasher(MessageLoop::TYPE_DEFAULT);
   1396   RunTest_Crasher(MessageLoop::TYPE_UI);
   1397   RunTest_Crasher(MessageLoop::TYPE_IO);
   1398 }
   1399 
   1400 TEST(MessageLoopTest, CrasherNasty) {
   1401   RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT);
   1402   RunTest_CrasherNasty(MessageLoop::TYPE_UI);
   1403   RunTest_CrasherNasty(MessageLoop::TYPE_IO);
   1404 }
   1405 #endif  // defined(OS_WIN)
   1406 
   1407 TEST(MessageLoopTest, Nesting) {
   1408   RunTest_Nesting(MessageLoop::TYPE_DEFAULT);
   1409   RunTest_Nesting(MessageLoop::TYPE_UI);
   1410   RunTest_Nesting(MessageLoop::TYPE_IO);
   1411 }
   1412 
   1413 TEST(MessageLoopTest, RecursiveDenial1) {
   1414   RunTest_RecursiveDenial1(MessageLoop::TYPE_DEFAULT);
   1415   RunTest_RecursiveDenial1(MessageLoop::TYPE_UI);
   1416   RunTest_RecursiveDenial1(MessageLoop::TYPE_IO);
   1417 }
   1418 
   1419 TEST(MessageLoopTest, RecursiveSupport1) {
   1420   RunTest_RecursiveSupport1(MessageLoop::TYPE_DEFAULT);
   1421   RunTest_RecursiveSupport1(MessageLoop::TYPE_UI);
   1422   RunTest_RecursiveSupport1(MessageLoop::TYPE_IO);
   1423 }
   1424 
   1425 #if defined(OS_WIN)
   1426 TEST(MessageLoopTest, RecursiveDenial2) {
   1427   RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT);
   1428   RunTest_RecursiveDenial2(MessageLoop::TYPE_UI);
   1429   RunTest_RecursiveDenial2(MessageLoop::TYPE_IO);
   1430 }
   1431 
   1432 TEST(MessageLoopTest, RecursiveSupport2) {
   1433   // This test requires a UI loop
   1434   RunTest_RecursiveSupport2(MessageLoop::TYPE_UI);
   1435 }
   1436 #endif  // defined(OS_WIN)
   1437 
   1438 TEST(MessageLoopTest, NonNestableWithNoNesting) {
   1439   RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_DEFAULT);
   1440   RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_UI);
   1441   RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_IO);
   1442 }
   1443 
   1444 TEST(MessageLoopTest, NonNestableInNestedLoop) {
   1445   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, false);
   1446   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, false);
   1447   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, false);
   1448 }
   1449 
   1450 TEST(MessageLoopTest, NonNestableDelayedInNestedLoop) {
   1451   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, true);
   1452   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, true);
   1453   RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, true);
   1454 }
   1455 
   1456 #if defined(OS_WIN)
   1457 TEST(MessageLoopTest, Dispatcher) {
   1458   // This test requires a UI loop
   1459   RunTest_Dispatcher(MessageLoop::TYPE_UI);
   1460 }
   1461 
   1462 TEST(MessageLoopTest, DispatcherWithMessageHook) {
   1463   // This test requires a UI loop
   1464   RunTest_DispatcherWithMessageHook(MessageLoop::TYPE_UI);
   1465 }
   1466 
   1467 TEST(MessageLoopTest, IOHandler) {
   1468   RunTest_IOHandler();
   1469 }
   1470 
   1471 TEST(MessageLoopTest, WaitForIO) {
   1472   RunTest_WaitForIO();
   1473 }
   1474 #endif  // defined(OS_WIN)
   1475 
   1476 #if defined(OS_POSIX)
   1477 
   1478 namespace {
   1479 
   1480 class QuitDelegate : public
   1481     base::MessagePumpLibevent::Watcher {
   1482  public:
   1483   virtual void OnFileCanWriteWithoutBlocking(int fd) {
   1484     MessageLoop::current()->Quit();
   1485   }
   1486   virtual void OnFileCanReadWithoutBlocking(int fd) {
   1487     MessageLoop::current()->Quit();
   1488   }
   1489 };
   1490 
   1491 }  // namespace
   1492 
   1493 TEST(MessageLoopTest, DISABLED_FileDescriptorWatcherOutlivesMessageLoop) {
   1494   // Simulate a MessageLoop that dies before an FileDescriptorWatcher.
   1495   // This could happen when people use the Singleton pattern or atexit.
   1496   // This is disabled for now because it fails (valgrind shows
   1497   // invalid reads), and it's not clear any code relies on this...
   1498   // TODO(dkegel): enable if it turns out we rely on this
   1499 
   1500   // Create a file descriptor.  Doesn't need to be readable or writable,
   1501   // as we don't need to actually get any notifications.
   1502   // pipe() is just the easiest way to do it.
   1503   int pipefds[2];
   1504   int err = pipe(pipefds);
   1505   ASSERT_TRUE(err == 0);
   1506   int fd = pipefds[1];
   1507   {
   1508     // Arrange for controller to live longer than message loop.
   1509     base::MessagePumpLibevent::FileDescriptorWatcher controller;
   1510     {
   1511       MessageLoopForIO message_loop;
   1512 
   1513       QuitDelegate delegate;
   1514       message_loop.WatchFileDescriptor(fd,
   1515           true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate);
   1516       // and don't run the message loop, just destroy it.
   1517     }
   1518   }
   1519   close(pipefds[0]);
   1520   close(pipefds[1]);
   1521 }
   1522 
   1523 TEST(MessageLoopTest, FileDescriptorWatcherDoubleStop) {
   1524   // Verify that it's ok to call StopWatchingFileDescriptor().
   1525   // (Errors only showed up in valgrind.)
   1526   int pipefds[2];
   1527   int err = pipe(pipefds);
   1528   ASSERT_TRUE(err == 0);
   1529   int fd = pipefds[1];
   1530   {
   1531     // Arrange for message loop to live longer than controller.
   1532     MessageLoopForIO message_loop;
   1533     {
   1534       base::MessagePumpLibevent::FileDescriptorWatcher controller;
   1535 
   1536       QuitDelegate delegate;
   1537       message_loop.WatchFileDescriptor(fd,
   1538           true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate);
   1539       controller.StopWatchingFileDescriptor();
   1540     }
   1541   }
   1542   close(pipefds[0]);
   1543   close(pipefds[1]);
   1544 }
   1545 
   1546 #endif  // defined(OS_POSIX)
   1547