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 "base/message_loop/message_loop_test.h"
      6 
      7 #include <stddef.h>
      8 
      9 #include <utility>
     10 
     11 #include "base/bind.h"
     12 #include "base/macros.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/run_loop.h"
     15 #include "base/single_thread_task_runner.h"
     16 #include "base/synchronization/waitable_event.h"
     17 #include "base/threading/thread.h"
     18 
     19 namespace base {
     20 namespace test {
     21 
     22 namespace {
     23 
     24 class Foo : public RefCounted<Foo> {
     25  public:
     26   Foo() : test_count_(0) {
     27   }
     28 
     29   void Test0() {
     30     ++test_count_;
     31   }
     32 
     33   void Test1ConstRef(const std::string& a) {
     34     ++test_count_;
     35     result_.append(a);
     36   }
     37 
     38   void Test1Ptr(std::string* a) {
     39     ++test_count_;
     40     result_.append(*a);
     41   }
     42 
     43   void Test1Int(int a) {
     44     test_count_ += a;
     45   }
     46 
     47   void Test2Ptr(std::string* a, std::string* b) {
     48     ++test_count_;
     49     result_.append(*a);
     50     result_.append(*b);
     51   }
     52 
     53   void Test2Mixed(const std::string& a, std::string* b) {
     54     ++test_count_;
     55     result_.append(a);
     56     result_.append(*b);
     57   }
     58 
     59   int test_count() const { return test_count_; }
     60   const std::string& result() const { return result_; }
     61 
     62  private:
     63   friend class RefCounted<Foo>;
     64 
     65   ~Foo() {}
     66 
     67   int test_count_;
     68   std::string result_;
     69 
     70   DISALLOW_COPY_AND_ASSIGN(Foo);
     71 };
     72 
     73 // This function runs slowly to simulate a large amount of work being done.
     74 void SlowFunc(TimeDelta pause, int* quit_counter) {
     75     PlatformThread::Sleep(pause);
     76     if (--(*quit_counter) == 0)
     77       MessageLoop::current()->QuitWhenIdle();
     78 }
     79 
     80 // This function records the time when Run was called in a Time object, which is
     81 // useful for building a variety of MessageLoop tests.
     82 // TODO(sky): remove?
     83 void RecordRunTimeFunc(Time* run_time, int* quit_counter) {
     84   *run_time = Time::Now();
     85 
     86     // Cause our Run function to take some time to execute.  As a result we can
     87     // count on subsequent RecordRunTimeFunc()s running at a future time,
     88     // without worry about the resolution of our system clock being an issue.
     89   SlowFunc(TimeDelta::FromMilliseconds(10), quit_counter);
     90 }
     91 
     92 }  // namespace
     93 
     94 void RunTest_PostTask(MessagePumpFactory factory) {
     95   std::unique_ptr<MessagePump> pump(factory());
     96   MessageLoop loop(std::move(pump));
     97   // Add tests to message loop
     98   scoped_refptr<Foo> foo(new Foo());
     99   std::string a("a"), b("b"), c("c"), d("d");
    100   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    101                                                   Bind(&Foo::Test0, foo.get()));
    102   MessageLoop::current()->task_runner()->PostTask(
    103       FROM_HERE, Bind(&Foo::Test1ConstRef, foo.get(), a));
    104   MessageLoop::current()->task_runner()->PostTask(
    105       FROM_HERE, Bind(&Foo::Test1Ptr, foo.get(), &b));
    106   MessageLoop::current()->task_runner()->PostTask(
    107       FROM_HERE, Bind(&Foo::Test1Int, foo.get(), 100));
    108   MessageLoop::current()->task_runner()->PostTask(
    109       FROM_HERE, Bind(&Foo::Test2Ptr, foo.get(), &a, &c));
    110   MessageLoop::current()->task_runner()->PostTask(
    111       FROM_HERE, Bind(&Foo::Test2Mixed, foo.get(), a, &d));
    112   // After all tests, post a message that will shut down the message loop
    113   MessageLoop::current()->task_runner()->PostTask(
    114       FROM_HERE,
    115       Bind(&MessageLoop::QuitWhenIdle, Unretained(MessageLoop::current())));
    116 
    117   // Now kick things off
    118   RunLoop().Run();
    119 
    120   EXPECT_EQ(foo->test_count(), 105);
    121   EXPECT_EQ(foo->result(), "abacad");
    122 }
    123 
    124 void RunTest_PostDelayedTask_Basic(MessagePumpFactory factory) {
    125   std::unique_ptr<MessagePump> pump(factory());
    126   MessageLoop loop(std::move(pump));
    127 
    128   // Test that PostDelayedTask results in a delayed task.
    129 
    130   const TimeDelta kDelay = TimeDelta::FromMilliseconds(100);
    131 
    132   int num_tasks = 1;
    133   Time run_time;
    134 
    135   loop.task_runner()->PostDelayedTask(
    136       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time, &num_tasks), kDelay);
    137 
    138   Time time_before_run = Time::Now();
    139   RunLoop().Run();
    140   Time time_after_run = Time::Now();
    141 
    142   EXPECT_EQ(0, num_tasks);
    143   EXPECT_LT(kDelay, time_after_run - time_before_run);
    144 }
    145 
    146 void RunTest_PostDelayedTask_InDelayOrder(MessagePumpFactory factory) {
    147   std::unique_ptr<MessagePump> pump(factory());
    148   MessageLoop loop(std::move(pump));
    149 
    150   // Test that two tasks with different delays run in the right order.
    151   int num_tasks = 2;
    152   Time run_time1, run_time2;
    153 
    154   loop.task_runner()->PostDelayedTask(
    155       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time1, &num_tasks),
    156       TimeDelta::FromMilliseconds(200));
    157   // If we get a large pause in execution (due to a context switch) here, this
    158   // test could fail.
    159   loop.task_runner()->PostDelayedTask(
    160       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
    161       TimeDelta::FromMilliseconds(10));
    162 
    163   RunLoop().Run();
    164   EXPECT_EQ(0, num_tasks);
    165 
    166   EXPECT_TRUE(run_time2 < run_time1);
    167 }
    168 
    169 void RunTest_PostDelayedTask_InPostOrder(MessagePumpFactory factory) {
    170   std::unique_ptr<MessagePump> pump(factory());
    171   MessageLoop loop(std::move(pump));
    172 
    173   // Test that two tasks with the same delay run in the order in which they
    174   // were posted.
    175   //
    176   // NOTE: This is actually an approximate test since the API only takes a
    177   // "delay" parameter, so we are not exactly simulating two tasks that get
    178   // posted at the exact same time.  It would be nice if the API allowed us to
    179   // specify the desired run time.
    180 
    181   const TimeDelta kDelay = TimeDelta::FromMilliseconds(100);
    182 
    183   int num_tasks = 2;
    184   Time run_time1, run_time2;
    185 
    186   loop.task_runner()->PostDelayedTask(
    187       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), kDelay);
    188   loop.task_runner()->PostDelayedTask(
    189       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), kDelay);
    190 
    191   RunLoop().Run();
    192   EXPECT_EQ(0, num_tasks);
    193 
    194   EXPECT_TRUE(run_time1 < run_time2);
    195 }
    196 
    197 void RunTest_PostDelayedTask_InPostOrder_2(MessagePumpFactory factory) {
    198   std::unique_ptr<MessagePump> pump(factory());
    199   MessageLoop loop(std::move(pump));
    200 
    201   // Test that a delayed task still runs after a normal tasks even if the
    202   // normal tasks take a long time to run.
    203 
    204   const TimeDelta kPause = TimeDelta::FromMilliseconds(50);
    205 
    206   int num_tasks = 2;
    207   Time run_time;
    208 
    209   loop.task_runner()->PostTask(FROM_HERE, Bind(&SlowFunc, kPause, &num_tasks));
    210   loop.task_runner()->PostDelayedTask(
    211       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time, &num_tasks),
    212       TimeDelta::FromMilliseconds(10));
    213 
    214   Time time_before_run = Time::Now();
    215   RunLoop().Run();
    216   Time time_after_run = Time::Now();
    217 
    218   EXPECT_EQ(0, num_tasks);
    219 
    220   EXPECT_LT(kPause, time_after_run - time_before_run);
    221 }
    222 
    223 void RunTest_PostDelayedTask_InPostOrder_3(MessagePumpFactory factory) {
    224   std::unique_ptr<MessagePump> pump(factory());
    225   MessageLoop loop(std::move(pump));
    226 
    227   // Test that a delayed task still runs after a pile of normal tasks.  The key
    228   // difference between this test and the previous one is that here we return
    229   // the MessageLoop a lot so we give the MessageLoop plenty of opportunities
    230   // to maybe run the delayed task.  It should know not to do so until the
    231   // delayed task's delay has passed.
    232 
    233   int num_tasks = 11;
    234   Time run_time1, run_time2;
    235 
    236   // Clutter the ML with tasks.
    237   for (int i = 1; i < num_tasks; ++i)
    238     loop.task_runner()->PostTask(
    239         FROM_HERE, Bind(&RecordRunTimeFunc, &run_time1, &num_tasks));
    240 
    241   loop.task_runner()->PostDelayedTask(
    242       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
    243       TimeDelta::FromMilliseconds(1));
    244 
    245   RunLoop().Run();
    246   EXPECT_EQ(0, num_tasks);
    247 
    248   EXPECT_TRUE(run_time2 > run_time1);
    249 }
    250 
    251 void RunTest_PostDelayedTask_SharedTimer(MessagePumpFactory factory) {
    252   std::unique_ptr<MessagePump> pump(factory());
    253   MessageLoop loop(std::move(pump));
    254 
    255   // Test that the interval of the timer, used to run the next delayed task, is
    256   // set to a value corresponding to when the next delayed task should run.
    257 
    258   // By setting num_tasks to 1, we ensure that the first task to run causes the
    259   // run loop to exit.
    260   int num_tasks = 1;
    261   Time run_time1, run_time2;
    262 
    263   loop.task_runner()->PostDelayedTask(
    264       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time1, &num_tasks),
    265       TimeDelta::FromSeconds(1000));
    266   loop.task_runner()->PostDelayedTask(
    267       FROM_HERE, Bind(&RecordRunTimeFunc, &run_time2, &num_tasks),
    268       TimeDelta::FromMilliseconds(10));
    269 
    270   Time start_time = Time::Now();
    271 
    272   RunLoop().Run();
    273   EXPECT_EQ(0, num_tasks);
    274 
    275   // Ensure that we ran in far less time than the slower timer.
    276   TimeDelta total_time = Time::Now() - start_time;
    277   EXPECT_GT(5000, total_time.InMilliseconds());
    278 
    279   // In case both timers somehow run at nearly the same time, sleep a little
    280   // and then run all pending to force them both to have run.  This is just
    281   // encouraging flakiness if there is any.
    282   PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
    283   RunLoop().RunUntilIdle();
    284 
    285   EXPECT_TRUE(run_time1.is_null());
    286   EXPECT_FALSE(run_time2.is_null());
    287 }
    288 
    289 // This is used to inject a test point for recording the destructor calls for
    290 // Closure objects send to MessageLoop::PostTask(). It is awkward usage since we
    291 // are trying to hook the actual destruction, which is not a common operation.
    292 class RecordDeletionProbe : public RefCounted<RecordDeletionProbe> {
    293  public:
    294   RecordDeletionProbe(RecordDeletionProbe* post_on_delete, bool* was_deleted)
    295       : post_on_delete_(post_on_delete), was_deleted_(was_deleted) {
    296   }
    297   void Run() {}
    298 
    299  private:
    300   friend class RefCounted<RecordDeletionProbe>;
    301 
    302   ~RecordDeletionProbe() {
    303     *was_deleted_ = true;
    304     if (post_on_delete_.get())
    305       MessageLoop::current()->task_runner()->PostTask(
    306           FROM_HERE, Bind(&RecordDeletionProbe::Run, post_on_delete_.get()));
    307   }
    308 
    309   scoped_refptr<RecordDeletionProbe> post_on_delete_;
    310   bool* was_deleted_;
    311 };
    312 
    313 void RunTest_EnsureDeletion(MessagePumpFactory factory) {
    314   bool a_was_deleted = false;
    315   bool b_was_deleted = false;
    316   {
    317     std::unique_ptr<MessagePump> pump(factory());
    318     MessageLoop loop(std::move(pump));
    319     loop.task_runner()->PostTask(
    320         FROM_HERE, Bind(&RecordDeletionProbe::Run,
    321                         new RecordDeletionProbe(NULL, &a_was_deleted)));
    322     // TODO(ajwong): Do we really need 1000ms here?
    323     loop.task_runner()->PostDelayedTask(
    324         FROM_HERE, Bind(&RecordDeletionProbe::Run,
    325                         new RecordDeletionProbe(NULL, &b_was_deleted)),
    326         TimeDelta::FromMilliseconds(1000));
    327   }
    328   EXPECT_TRUE(a_was_deleted);
    329   EXPECT_TRUE(b_was_deleted);
    330 }
    331 
    332 void RunTest_EnsureDeletion_Chain(MessagePumpFactory factory) {
    333   bool a_was_deleted = false;
    334   bool b_was_deleted = false;
    335   bool c_was_deleted = false;
    336   {
    337     std::unique_ptr<MessagePump> pump(factory());
    338     MessageLoop loop(std::move(pump));
    339     // The scoped_refptr for each of the below is held either by the chained
    340     // RecordDeletionProbe, or the bound RecordDeletionProbe::Run() callback.
    341     RecordDeletionProbe* a = new RecordDeletionProbe(NULL, &a_was_deleted);
    342     RecordDeletionProbe* b = new RecordDeletionProbe(a, &b_was_deleted);
    343     RecordDeletionProbe* c = new RecordDeletionProbe(b, &c_was_deleted);
    344     loop.task_runner()->PostTask(FROM_HERE, Bind(&RecordDeletionProbe::Run, c));
    345   }
    346   EXPECT_TRUE(a_was_deleted);
    347   EXPECT_TRUE(b_was_deleted);
    348   EXPECT_TRUE(c_was_deleted);
    349 }
    350 
    351 void NestingFunc(int* depth) {
    352   if (*depth > 0) {
    353     *depth -= 1;
    354     MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    355                                                     Bind(&NestingFunc, depth));
    356 
    357     MessageLoop::current()->SetNestableTasksAllowed(true);
    358     RunLoop().Run();
    359   }
    360   MessageLoop::current()->QuitWhenIdle();
    361 }
    362 
    363 void RunTest_Nesting(MessagePumpFactory factory) {
    364   std::unique_ptr<MessagePump> pump(factory());
    365   MessageLoop loop(std::move(pump));
    366 
    367   int depth = 100;
    368   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    369                                                   Bind(&NestingFunc, &depth));
    370   RunLoop().Run();
    371   EXPECT_EQ(depth, 0);
    372 }
    373 
    374 // A NestingObserver that tracks the number of nested message loop starts it
    375 // has seen.
    376 class TestNestingObserver : public MessageLoop::NestingObserver {
    377  public:
    378   TestNestingObserver() {}
    379   ~TestNestingObserver() override {}
    380 
    381   int begin_nested_loop_count() const { return begin_nested_loop_count_; }
    382 
    383   // MessageLoop::NestingObserver:
    384   void OnBeginNestedMessageLoop() override { begin_nested_loop_count_++; }
    385 
    386  private:
    387   int begin_nested_loop_count_ = 0;
    388 
    389   DISALLOW_COPY_AND_ASSIGN(TestNestingObserver);
    390 };
    391 
    392 void ExpectOneBeginNestedLoop(TestNestingObserver* observer) {
    393   EXPECT_EQ(1, observer->begin_nested_loop_count());
    394 }
    395 
    396 // Starts a nested message loop.
    397 void RunNestedLoop(TestNestingObserver* observer,
    398                    const Closure& quit_outer_loop) {
    399   // The nested loop hasn't started yet.
    400   EXPECT_EQ(0, observer->begin_nested_loop_count());
    401 
    402   MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
    403   RunLoop nested_loop;
    404   // Verify that by the time the first task is run the observer has seen the
    405   // message loop begin.
    406   MessageLoop::current()->task_runner()->PostTask(
    407       FROM_HERE, Bind(&ExpectOneBeginNestedLoop, observer));
    408   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    409                                                   nested_loop.QuitClosure());
    410   nested_loop.Run();
    411 
    412   // Quitting message loops doesn't change the begin count.
    413   EXPECT_EQ(1, observer->begin_nested_loop_count());
    414 
    415   quit_outer_loop.Run();
    416 }
    417 
    418 // Tests that a NestingObserver is notified when a nested message loop begins.
    419 void RunTest_NestingObserver(MessagePumpFactory factory) {
    420   std::unique_ptr<MessagePump> pump(factory());
    421   MessageLoop outer_loop(std::move(pump));
    422 
    423   // Observe the outer loop for nested message loops beginning.
    424   TestNestingObserver nesting_observer;
    425   outer_loop.AddNestingObserver(&nesting_observer);
    426 
    427   // Post a task that runs a nested message loop.
    428   outer_loop.task_runner()->PostTask(FROM_HERE,
    429                                      Bind(&RunNestedLoop, &nesting_observer,
    430                                           outer_loop.QuitWhenIdleClosure()));
    431   RunLoop().Run();
    432 
    433   outer_loop.RemoveNestingObserver(&nesting_observer);
    434 }
    435 
    436 enum TaskType {
    437   MESSAGEBOX,
    438   ENDDIALOG,
    439   RECURSIVE,
    440   TIMEDMESSAGELOOP,
    441   QUITMESSAGELOOP,
    442   ORDERED,
    443   PUMPS,
    444   SLEEP,
    445   RUNS,
    446 };
    447 
    448 struct TaskItem {
    449   TaskItem(TaskType t, int c, bool s)
    450       : type(t),
    451         cookie(c),
    452         start(s) {
    453   }
    454 
    455   TaskType type;
    456   int cookie;
    457   bool start;
    458 
    459   bool operator == (const TaskItem& other) const {
    460     return type == other.type && cookie == other.cookie && start == other.start;
    461   }
    462 };
    463 
    464 std::ostream& operator <<(std::ostream& os, TaskType type) {
    465   switch (type) {
    466   case MESSAGEBOX:        os << "MESSAGEBOX"; break;
    467   case ENDDIALOG:         os << "ENDDIALOG"; break;
    468   case RECURSIVE:         os << "RECURSIVE"; break;
    469   case TIMEDMESSAGELOOP:  os << "TIMEDMESSAGELOOP"; break;
    470   case QUITMESSAGELOOP:   os << "QUITMESSAGELOOP"; break;
    471   case ORDERED:          os << "ORDERED"; break;
    472   case PUMPS:             os << "PUMPS"; break;
    473   case SLEEP:             os << "SLEEP"; break;
    474   default:
    475     NOTREACHED();
    476     os << "Unknown TaskType";
    477     break;
    478   }
    479   return os;
    480 }
    481 
    482 std::ostream& operator <<(std::ostream& os, const TaskItem& item) {
    483   if (item.start)
    484     return os << item.type << " " << item.cookie << " starts";
    485   else
    486     return os << item.type << " " << item.cookie << " ends";
    487 }
    488 
    489 class TaskList {
    490  public:
    491   void RecordStart(TaskType type, int cookie) {
    492     TaskItem item(type, cookie, true);
    493     DVLOG(1) << item;
    494     task_list_.push_back(item);
    495   }
    496 
    497   void RecordEnd(TaskType type, int cookie) {
    498     TaskItem item(type, cookie, false);
    499     DVLOG(1) << item;
    500     task_list_.push_back(item);
    501   }
    502 
    503   size_t Size() {
    504     return task_list_.size();
    505   }
    506 
    507   TaskItem Get(int n)  {
    508     return task_list_[n];
    509   }
    510 
    511  private:
    512   std::vector<TaskItem> task_list_;
    513 };
    514 
    515 void RecursiveFunc(TaskList* order, int cookie, int depth,
    516                    bool is_reentrant) {
    517   order->RecordStart(RECURSIVE, cookie);
    518   if (depth > 0) {
    519     if (is_reentrant)
    520       MessageLoop::current()->SetNestableTasksAllowed(true);
    521     MessageLoop::current()->task_runner()->PostTask(
    522         FROM_HERE,
    523         Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant));
    524   }
    525   order->RecordEnd(RECURSIVE, cookie);
    526 }
    527 
    528 void QuitFunc(TaskList* order, int cookie) {
    529   order->RecordStart(QUITMESSAGELOOP, cookie);
    530   MessageLoop::current()->QuitWhenIdle();
    531   order->RecordEnd(QUITMESSAGELOOP, cookie);
    532 }
    533 void RunTest_RecursiveDenial1(MessagePumpFactory factory) {
    534   std::unique_ptr<MessagePump> pump(factory());
    535   MessageLoop loop(std::move(pump));
    536 
    537   EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed());
    538   TaskList order;
    539   MessageLoop::current()->task_runner()->PostTask(
    540       FROM_HERE, Bind(&RecursiveFunc, &order, 1, 2, false));
    541   MessageLoop::current()->task_runner()->PostTask(
    542       FROM_HERE, Bind(&RecursiveFunc, &order, 2, 2, false));
    543   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    544                                                   Bind(&QuitFunc, &order, 3));
    545 
    546   RunLoop().Run();
    547 
    548   // FIFO order.
    549   ASSERT_EQ(14U, order.Size());
    550   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
    551   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
    552   EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
    553   EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
    554   EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
    555   EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
    556   EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true));
    557   EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false));
    558   EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
    559   EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
    560   EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
    561   EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
    562   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true));
    563   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false));
    564 }
    565 
    566 void RecursiveSlowFunc(TaskList* order, int cookie, int depth,
    567                        bool is_reentrant) {
    568   RecursiveFunc(order, cookie, depth, is_reentrant);
    569   PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));
    570 }
    571 
    572 void OrderedFunc(TaskList* order, int cookie) {
    573   order->RecordStart(ORDERED, cookie);
    574   order->RecordEnd(ORDERED, cookie);
    575 }
    576 
    577 void RunTest_RecursiveDenial3(MessagePumpFactory factory) {
    578   std::unique_ptr<MessagePump> pump(factory());
    579   MessageLoop loop(std::move(pump));
    580 
    581   EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed());
    582   TaskList order;
    583   MessageLoop::current()->task_runner()->PostTask(
    584       FROM_HERE, Bind(&RecursiveSlowFunc, &order, 1, 2, false));
    585   MessageLoop::current()->task_runner()->PostTask(
    586       FROM_HERE, Bind(&RecursiveSlowFunc, &order, 2, 2, false));
    587   MessageLoop::current()->task_runner()->PostDelayedTask(
    588       FROM_HERE, Bind(&OrderedFunc, &order, 3), TimeDelta::FromMilliseconds(5));
    589   MessageLoop::current()->task_runner()->PostDelayedTask(
    590       FROM_HERE, Bind(&QuitFunc, &order, 4), TimeDelta::FromMilliseconds(5));
    591 
    592   RunLoop().Run();
    593 
    594   // FIFO order.
    595   ASSERT_EQ(16U, order.Size());
    596   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
    597   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
    598   EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
    599   EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
    600   EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 1, true));
    601   EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 1, false));
    602   EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 3, true));
    603   EXPECT_EQ(order.Get(7), TaskItem(ORDERED, 3, false));
    604   EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
    605   EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
    606   EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 4, true));
    607   EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 4, false));
    608   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 1, true));
    609   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, false));
    610   EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 2, true));
    611   EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 2, false));
    612 }
    613 
    614 void RunTest_RecursiveSupport1(MessagePumpFactory factory) {
    615   std::unique_ptr<MessagePump> pump(factory());
    616   MessageLoop loop(std::move(pump));
    617 
    618   TaskList order;
    619   MessageLoop::current()->task_runner()->PostTask(
    620       FROM_HERE, Bind(&RecursiveFunc, &order, 1, 2, true));
    621   MessageLoop::current()->task_runner()->PostTask(
    622       FROM_HERE, Bind(&RecursiveFunc, &order, 2, 2, true));
    623   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    624                                                   Bind(&QuitFunc, &order, 3));
    625 
    626   RunLoop().Run();
    627 
    628   // FIFO order.
    629   ASSERT_EQ(14U, order.Size());
    630   EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true));
    631   EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false));
    632   EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true));
    633   EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false));
    634   EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
    635   EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
    636   EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true));
    637   EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false));
    638   EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true));
    639   EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false));
    640   EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true));
    641   EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false));
    642   EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true));
    643   EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false));
    644 }
    645 
    646 // Tests that non nestable tasks run in FIFO if there are no nested loops.
    647 void RunTest_NonNestableWithNoNesting(MessagePumpFactory factory) {
    648   std::unique_ptr<MessagePump> pump(factory());
    649   MessageLoop loop(std::move(pump));
    650 
    651   TaskList order;
    652 
    653   MessageLoop::current()->task_runner()->PostNonNestableTask(
    654       FROM_HERE,
    655       Bind(&OrderedFunc, &order, 1));
    656   MessageLoop::current()->task_runner()->PostTask(
    657       FROM_HERE,
    658       Bind(&OrderedFunc, &order, 2));
    659   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    660                                                   Bind(&QuitFunc, &order, 3));
    661   RunLoop().Run();
    662 
    663   // FIFO order.
    664   ASSERT_EQ(6U, order.Size());
    665   EXPECT_EQ(order.Get(0), TaskItem(ORDERED, 1, true));
    666   EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 1, false));
    667   EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 2, true));
    668   EXPECT_EQ(order.Get(3), TaskItem(ORDERED, 2, false));
    669   EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true));
    670   EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false));
    671 }
    672 
    673 void FuncThatPumps(TaskList* order, int cookie) {
    674   order->RecordStart(PUMPS, cookie);
    675   {
    676     MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
    677     RunLoop().RunUntilIdle();
    678   }
    679   order->RecordEnd(PUMPS, cookie);
    680 }
    681 
    682 void SleepFunc(TaskList* order, int cookie, TimeDelta delay) {
    683   order->RecordStart(SLEEP, cookie);
    684   PlatformThread::Sleep(delay);
    685   order->RecordEnd(SLEEP, cookie);
    686 }
    687 
    688 // Tests that non nestable tasks don't run when there's code in the call stack.
    689 void RunTest_NonNestableInNestedLoop(MessagePumpFactory factory) {
    690   std::unique_ptr<MessagePump> pump(factory());
    691   MessageLoop loop(std::move(pump));
    692 
    693   TaskList order;
    694 
    695   MessageLoop::current()->task_runner()->PostTask(
    696       FROM_HERE,
    697       Bind(&FuncThatPumps, &order, 1));
    698   MessageLoop::current()->task_runner()->PostNonNestableTask(
    699       FROM_HERE,
    700       Bind(&OrderedFunc, &order, 2));
    701   MessageLoop::current()->task_runner()->PostTask(
    702       FROM_HERE,
    703       Bind(&OrderedFunc, &order, 3));
    704   MessageLoop::current()->task_runner()->PostTask(
    705       FROM_HERE,
    706       Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50)));
    707   MessageLoop::current()->task_runner()->PostTask(
    708       FROM_HERE,
    709       Bind(&OrderedFunc, &order, 5));
    710   MessageLoop::current()->task_runner()->PostNonNestableTask(
    711       FROM_HERE,
    712       Bind(&QuitFunc, &order, 6));
    713 
    714   RunLoop().Run();
    715 
    716   // FIFO order.
    717   ASSERT_EQ(12U, order.Size());
    718   EXPECT_EQ(order.Get(0), TaskItem(PUMPS, 1, true));
    719   EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 3, true));
    720   EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 3, false));
    721   EXPECT_EQ(order.Get(3), TaskItem(SLEEP, 4, true));
    722   EXPECT_EQ(order.Get(4), TaskItem(SLEEP, 4, false));
    723   EXPECT_EQ(order.Get(5), TaskItem(ORDERED, 5, true));
    724   EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 5, false));
    725   EXPECT_EQ(order.Get(7), TaskItem(PUMPS, 1, false));
    726   EXPECT_EQ(order.Get(8), TaskItem(ORDERED, 2, true));
    727   EXPECT_EQ(order.Get(9), TaskItem(ORDERED, 2, false));
    728   EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 6, true));
    729   EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 6, false));
    730 }
    731 
    732 void FuncThatRuns(TaskList* order, int cookie, RunLoop* run_loop) {
    733   order->RecordStart(RUNS, cookie);
    734   {
    735     MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
    736     run_loop->Run();
    737   }
    738   order->RecordEnd(RUNS, cookie);
    739 }
    740 
    741 void FuncThatQuitsNow() {
    742   MessageLoop::current()->QuitNow();
    743 }
    744 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
    745 void RunTest_QuitNow(MessagePumpFactory factory) {
    746   std::unique_ptr<MessagePump> pump(factory());
    747   MessageLoop loop(std::move(pump));
    748 
    749   TaskList order;
    750 
    751   RunLoop run_loop;
    752 
    753   MessageLoop::current()->task_runner()->PostTask(
    754       FROM_HERE, Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop)));
    755   MessageLoop::current()->task_runner()->PostTask(
    756       FROM_HERE, Bind(&OrderedFunc, &order, 2));
    757   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    758                                                   Bind(&FuncThatQuitsNow));
    759   MessageLoop::current()->task_runner()->PostTask(
    760       FROM_HERE, Bind(&OrderedFunc, &order, 3));
    761   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    762                                                   Bind(&FuncThatQuitsNow));
    763   MessageLoop::current()->task_runner()->PostTask(
    764       FROM_HERE, Bind(&OrderedFunc, &order, 4));  // never runs
    765 
    766   RunLoop().Run();
    767 
    768   ASSERT_EQ(6U, order.Size());
    769   int task_index = 0;
    770   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
    771   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
    772   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
    773   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
    774   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true));
    775   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false));
    776   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
    777 }
    778 
    779 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
    780 void RunTest_RunLoopQuitTop(MessagePumpFactory factory) {
    781   std::unique_ptr<MessagePump> pump(factory());
    782   MessageLoop loop(std::move(pump));
    783 
    784   TaskList order;
    785 
    786   RunLoop outer_run_loop;
    787   RunLoop nested_run_loop;
    788 
    789   MessageLoop::current()->task_runner()->PostTask(
    790       FROM_HERE, Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
    791   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    792                                                   outer_run_loop.QuitClosure());
    793   MessageLoop::current()->task_runner()->PostTask(
    794       FROM_HERE, Bind(&OrderedFunc, &order, 2));
    795   MessageLoop::current()->task_runner()->PostTask(
    796       FROM_HERE, nested_run_loop.QuitClosure());
    797 
    798   outer_run_loop.Run();
    799 
    800   ASSERT_EQ(4U, order.Size());
    801   int task_index = 0;
    802   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
    803   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
    804   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
    805   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
    806   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
    807 }
    808 
    809 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
    810 void RunTest_RunLoopQuitNested(MessagePumpFactory factory) {
    811   std::unique_ptr<MessagePump> pump(factory());
    812   MessageLoop loop(std::move(pump));
    813 
    814   TaskList order;
    815 
    816   RunLoop outer_run_loop;
    817   RunLoop nested_run_loop;
    818 
    819   MessageLoop::current()->task_runner()->PostTask(
    820       FROM_HERE, Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
    821   MessageLoop::current()->task_runner()->PostTask(
    822       FROM_HERE, nested_run_loop.QuitClosure());
    823   MessageLoop::current()->task_runner()->PostTask(
    824       FROM_HERE, Bind(&OrderedFunc, &order, 2));
    825   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    826                                                   outer_run_loop.QuitClosure());
    827 
    828   outer_run_loop.Run();
    829 
    830   ASSERT_EQ(4U, order.Size());
    831   int task_index = 0;
    832   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
    833   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
    834   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
    835   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
    836   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
    837 }
    838 
    839 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
    840 void RunTest_RunLoopQuitBogus(MessagePumpFactory factory) {
    841   std::unique_ptr<MessagePump> pump(factory());
    842   MessageLoop loop(std::move(pump));
    843 
    844   TaskList order;
    845 
    846   RunLoop outer_run_loop;
    847   RunLoop nested_run_loop;
    848   RunLoop bogus_run_loop;
    849 
    850   MessageLoop::current()->task_runner()->PostTask(
    851       FROM_HERE, Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop)));
    852   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    853                                                   bogus_run_loop.QuitClosure());
    854   MessageLoop::current()->task_runner()->PostTask(
    855       FROM_HERE, Bind(&OrderedFunc, &order, 2));
    856   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    857                                                   outer_run_loop.QuitClosure());
    858   MessageLoop::current()->task_runner()->PostTask(
    859       FROM_HERE, nested_run_loop.QuitClosure());
    860 
    861   outer_run_loop.Run();
    862 
    863   ASSERT_EQ(4U, order.Size());
    864   int task_index = 0;
    865   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
    866   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
    867   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
    868   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
    869   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
    870 }
    871 
    872 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run.
    873 void RunTest_RunLoopQuitDeep(MessagePumpFactory factory) {
    874   std::unique_ptr<MessagePump> pump(factory());
    875   MessageLoop loop(std::move(pump));
    876 
    877   TaskList order;
    878 
    879   RunLoop outer_run_loop;
    880   RunLoop nested_loop1;
    881   RunLoop nested_loop2;
    882   RunLoop nested_loop3;
    883   RunLoop nested_loop4;
    884 
    885   MessageLoop::current()->task_runner()->PostTask(
    886       FROM_HERE, Bind(&FuncThatRuns, &order, 1, Unretained(&nested_loop1)));
    887   MessageLoop::current()->task_runner()->PostTask(
    888       FROM_HERE, Bind(&FuncThatRuns, &order, 2, Unretained(&nested_loop2)));
    889   MessageLoop::current()->task_runner()->PostTask(
    890       FROM_HERE, Bind(&FuncThatRuns, &order, 3, Unretained(&nested_loop3)));
    891   MessageLoop::current()->task_runner()->PostTask(
    892       FROM_HERE, Bind(&FuncThatRuns, &order, 4, Unretained(&nested_loop4)));
    893   MessageLoop::current()->task_runner()->PostTask(
    894       FROM_HERE, Bind(&OrderedFunc, &order, 5));
    895   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    896                                                   outer_run_loop.QuitClosure());
    897   MessageLoop::current()->task_runner()->PostTask(
    898       FROM_HERE, Bind(&OrderedFunc, &order, 6));
    899   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    900                                                   nested_loop1.QuitClosure());
    901   MessageLoop::current()->task_runner()->PostTask(
    902       FROM_HERE, Bind(&OrderedFunc, &order, 7));
    903   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    904                                                   nested_loop2.QuitClosure());
    905   MessageLoop::current()->task_runner()->PostTask(
    906       FROM_HERE, Bind(&OrderedFunc, &order, 8));
    907   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    908                                                   nested_loop3.QuitClosure());
    909   MessageLoop::current()->task_runner()->PostTask(
    910       FROM_HERE, Bind(&OrderedFunc, &order, 9));
    911   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    912                                                   nested_loop4.QuitClosure());
    913   MessageLoop::current()->task_runner()->PostTask(
    914       FROM_HERE, Bind(&OrderedFunc, &order, 10));
    915 
    916   outer_run_loop.Run();
    917 
    918   ASSERT_EQ(18U, order.Size());
    919   int task_index = 0;
    920   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
    921   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, true));
    922   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, true));
    923   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, true));
    924   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, true));
    925   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, false));
    926   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 6, true));
    927   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 6, false));
    928   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 7, true));
    929   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 7, false));
    930   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 8, true));
    931   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 8, false));
    932   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 9, true));
    933   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 9, false));
    934   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, false));
    935   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, false));
    936   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, false));
    937   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
    938   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
    939 }
    940 
    941 // Tests RunLoopQuit works before RunWithID.
    942 void RunTest_RunLoopQuitOrderBefore(MessagePumpFactory factory) {
    943   std::unique_ptr<MessagePump> pump(factory());
    944   MessageLoop loop(std::move(pump));
    945 
    946   TaskList order;
    947 
    948   RunLoop run_loop;
    949 
    950   run_loop.Quit();
    951 
    952   MessageLoop::current()->task_runner()->PostTask(
    953       FROM_HERE, Bind(&OrderedFunc, &order, 1));  // never runs
    954   MessageLoop::current()->task_runner()->PostTask(
    955       FROM_HERE, Bind(&FuncThatQuitsNow));  // never runs
    956 
    957   run_loop.Run();
    958 
    959   ASSERT_EQ(0U, order.Size());
    960 }
    961 
    962 // Tests RunLoopQuit works during RunWithID.
    963 void RunTest_RunLoopQuitOrderDuring(MessagePumpFactory factory) {
    964   std::unique_ptr<MessagePump> pump(factory());
    965   MessageLoop loop(std::move(pump));
    966 
    967   TaskList order;
    968 
    969   RunLoop run_loop;
    970 
    971   MessageLoop::current()->task_runner()->PostTask(
    972       FROM_HERE, Bind(&OrderedFunc, &order, 1));
    973   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
    974                                                   run_loop.QuitClosure());
    975   MessageLoop::current()->task_runner()->PostTask(
    976       FROM_HERE, Bind(&OrderedFunc, &order, 2));  // never runs
    977   MessageLoop::current()->task_runner()->PostTask(
    978       FROM_HERE, Bind(&FuncThatQuitsNow));  // never runs
    979 
    980   run_loop.Run();
    981 
    982   ASSERT_EQ(2U, order.Size());
    983   int task_index = 0;
    984   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, true));
    985   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, false));
    986   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
    987 }
    988 
    989 // Tests RunLoopQuit works after RunWithID.
    990 void RunTest_RunLoopQuitOrderAfter(MessagePumpFactory factory) {
    991   std::unique_ptr<MessagePump> pump(factory());
    992   MessageLoop loop(std::move(pump));
    993 
    994   TaskList order;
    995 
    996   RunLoop run_loop;
    997 
    998   MessageLoop::current()->task_runner()->PostTask(
    999       FROM_HERE, Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop)));
   1000   MessageLoop::current()->task_runner()->PostTask(
   1001       FROM_HERE, Bind(&OrderedFunc, &order, 2));
   1002   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
   1003                                                   Bind(&FuncThatQuitsNow));
   1004   MessageLoop::current()->task_runner()->PostTask(
   1005       FROM_HERE, Bind(&OrderedFunc, &order, 3));
   1006   MessageLoop::current()->task_runner()->PostTask(
   1007       FROM_HERE, run_loop.QuitClosure());  // has no affect
   1008   MessageLoop::current()->task_runner()->PostTask(
   1009       FROM_HERE, Bind(&OrderedFunc, &order, 4));
   1010   MessageLoop::current()->task_runner()->PostTask(FROM_HERE,
   1011                                                   Bind(&FuncThatQuitsNow));
   1012 
   1013   RunLoop outer_run_loop;
   1014   outer_run_loop.Run();
   1015 
   1016   ASSERT_EQ(8U, order.Size());
   1017   int task_index = 0;
   1018   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true));
   1019   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true));
   1020   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false));
   1021   EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false));
   1022   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true));
   1023   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false));
   1024   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, true));
   1025   EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, false));
   1026   EXPECT_EQ(static_cast<size_t>(task_index), order.Size());
   1027 }
   1028 
   1029 void PostNTasksThenQuit(int posts_remaining) {
   1030   if (posts_remaining > 1) {
   1031     MessageLoop::current()->task_runner()->PostTask(
   1032         FROM_HERE, Bind(&PostNTasksThenQuit, posts_remaining - 1));
   1033   } else {
   1034     MessageLoop::current()->QuitWhenIdle();
   1035   }
   1036 }
   1037 
   1038 // There was a bug in the MessagePumpGLib where posting tasks recursively
   1039 // caused the message loop to hang, due to the buffer of the internal pipe
   1040 // becoming full. Test all MessageLoop types to ensure this issue does not
   1041 // exist in other MessagePumps.
   1042 //
   1043 // On Linux, the pipe buffer size is 64KiB by default. The bug caused one
   1044 // byte accumulated in the pipe per two posts, so we should repeat 128K
   1045 // times to reproduce the bug.
   1046 void RunTest_RecursivePosts(MessagePumpFactory factory) {
   1047   const int kNumTimes = 1 << 17;
   1048   std::unique_ptr<MessagePump> pump(factory());
   1049   MessageLoop loop(std::move(pump));
   1050   loop.task_runner()->PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, kNumTimes));
   1051   RunLoop().Run();
   1052 }
   1053 
   1054 }  // namespace test
   1055 }  // namespace base
   1056