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