| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/message_loop/message_loop_proxy_impl.h" | 13 #include "base/message_loop/message_loop_proxy_impl.h" |
| 14 #include "base/message_loop/message_loop_test.h" |
| 14 #include "base/pending_task.h" | 15 #include "base/pending_task.h" |
| 15 #include "base/posix/eintr_wrapper.h" | 16 #include "base/posix/eintr_wrapper.h" |
| 16 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
| 17 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
| 18 #include "base/thread_task_runner_handle.h" | 19 #include "base/thread_task_runner_handle.h" |
| 19 #include "base/threading/platform_thread.h" | 20 #include "base/threading/platform_thread.h" |
| 20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 23 |
| 23 #if defined(OS_WIN) | 24 #if defined(OS_WIN) |
| 24 #include "base/message_loop/message_pump_win.h" | 25 #include "base/message_loop/message_pump_win.h" |
| 25 #include "base/win/scoped_handle.h" | 26 #include "base/win/scoped_handle.h" |
| 26 #endif | 27 #endif |
| 27 | 28 |
| 28 namespace base { | 29 namespace base { |
| 29 | 30 |
| 30 // TODO(darin): Platform-specific MessageLoop tests should be grouped together | 31 // TODO(darin): Platform-specific MessageLoop tests should be grouped together |
| 31 // to avoid chopping this file up with so many #ifdefs. | 32 // to avoid chopping this file up with so many #ifdefs. |
| 32 | 33 |
| 33 namespace { | 34 namespace { |
| 34 | 35 |
| 36 MessagePump* TypeDefaultMessagePumpFactory() { |
| 37 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_DEFAULT); |
| 38 } |
| 39 |
| 40 MessagePump* TypeIOMessagePumpFactory() { |
| 41 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_IO); |
| 42 } |
| 43 |
| 44 MessagePump* TypeUIMessagePumpFactory() { |
| 45 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_UI); |
| 46 } |
| 47 |
| 35 class Foo : public RefCounted<Foo> { | 48 class Foo : public RefCounted<Foo> { |
| 36 public: | 49 public: |
| 37 Foo() : test_count_(0) { | 50 Foo() : test_count_(0) { |
| 38 } | 51 } |
| 39 | 52 |
| 40 void Test0() { | 53 void Test0() { |
| 41 ++test_count_; | 54 ++test_count_; |
| 42 } | 55 } |
| 43 | 56 |
| 44 void Test1ConstRef(const std::string& a) { | 57 void Test1ConstRef(const std::string& a) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 72 | 85 |
| 73 private: | 86 private: |
| 74 friend class RefCounted<Foo>; | 87 friend class RefCounted<Foo>; |
| 75 | 88 |
| 76 ~Foo() {} | 89 ~Foo() {} |
| 77 | 90 |
| 78 int test_count_; | 91 int test_count_; |
| 79 std::string result_; | 92 std::string result_; |
| 80 }; | 93 }; |
| 81 | 94 |
| 82 void RunTest_PostTask(MessageLoop::Type message_loop_type) { | 95 #if defined(OS_WIN) |
| 83 MessageLoop loop(message_loop_type); | |
| 84 | |
| 85 // Add tests to message loop | |
| 86 scoped_refptr<Foo> foo(new Foo()); | |
| 87 std::string a("a"), b("b"), c("c"), d("d"); | |
| 88 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 89 &Foo::Test0, foo.get())); | |
| 90 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 91 &Foo::Test1ConstRef, foo.get(), a)); | |
| 92 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 93 &Foo::Test1Ptr, foo.get(), &b)); | |
| 94 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 95 &Foo::Test1Int, foo.get(), 100)); | |
| 96 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 97 &Foo::Test2Ptr, foo.get(), &a, &c)); | |
| 98 | |
| 99 // TryPost with no contention. It must succeed. | |
| 100 EXPECT_TRUE(MessageLoop::current()->TryPostTask(FROM_HERE, Bind( | |
| 101 &Foo::Test2Mixed, foo.get(), a, &d))); | |
| 102 | |
| 103 // TryPost with simulated contention. It must fail. We wait for a helper | |
| 104 // thread to lock the queue, we TryPost on this thread and finally we | |
| 105 // signal the helper to unlock and exit. | |
| 106 WaitableEvent wait(true, false); | |
| 107 WaitableEvent signal(true, false); | |
| 108 Thread thread("RunTest_PostTask_helper"); | |
| 109 thread.Start(); | |
| 110 thread.message_loop()->PostTask( | |
| 111 FROM_HERE, | |
| 112 Bind(&MessageLoop::LockWaitUnLockForTesting, | |
| 113 base::Unretained(MessageLoop::current()), | |
| 114 &wait, | |
| 115 &signal)); | |
| 116 | |
| 117 wait.Wait(); | |
| 118 EXPECT_FALSE(MessageLoop::current()->TryPostTask(FROM_HERE, Bind( | |
| 119 &Foo::Test2Mixed, foo.get(), a, &d))); | |
| 120 signal.Signal(); | |
| 121 | |
| 122 // After all tests, post a message that will shut down the message loop | |
| 123 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 124 &MessageLoop::Quit, Unretained(MessageLoop::current()))); | |
| 125 | |
| 126 // Now kick things off | |
| 127 MessageLoop::current()->Run(); | |
| 128 | |
| 129 EXPECT_EQ(foo->test_count(), 105); | |
| 130 EXPECT_EQ(foo->result(), "abacad"); | |
| 131 } | |
| 132 | |
| 133 void RunTest_PostTask_SEH(MessageLoop::Type message_loop_type) { | |
| 134 MessageLoop loop(message_loop_type); | |
| 135 | |
| 136 // Add tests to message loop | |
| 137 scoped_refptr<Foo> foo(new Foo()); | |
| 138 std::string a("a"), b("b"), c("c"), d("d"); | |
| 139 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 140 &Foo::Test0, foo.get())); | |
| 141 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 142 &Foo::Test1ConstRef, foo.get(), a)); | |
| 143 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 144 &Foo::Test1Ptr, foo.get(), &b)); | |
| 145 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 146 &Foo::Test1Int, foo.get(), 100)); | |
| 147 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 148 &Foo::Test2Ptr, foo.get(), &a, &c)); | |
| 149 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 150 &Foo::Test2Mixed, foo.get(), a, &d)); | |
| 151 | |
| 152 // After all tests, post a message that will shut down the message loop | |
| 153 MessageLoop::current()->PostTask(FROM_HERE, Bind( | |
| 154 &MessageLoop::Quit, Unretained(MessageLoop::current()))); | |
| 155 | |
| 156 // Now kick things off with the SEH block active. | |
| 157 MessageLoop::current()->set_exception_restoration(true); | |
| 158 MessageLoop::current()->Run(); | |
| 159 MessageLoop::current()->set_exception_restoration(false); | |
| 160 | |
| 161 EXPECT_EQ(foo->test_count(), 105); | |
| 162 EXPECT_EQ(foo->result(), "abacad"); | |
| 163 } | |
| 164 | 96 |
| 165 // This function runs slowly to simulate a large amount of work being done. | 97 // This function runs slowly to simulate a large amount of work being done. |
| 166 static void SlowFunc(TimeDelta pause, int* quit_counter) { | 98 static void SlowFunc(TimeDelta pause, int* quit_counter) { |
| 167 PlatformThread::Sleep(pause); | 99 PlatformThread::Sleep(pause); |
| 168 if (--(*quit_counter) == 0) | 100 if (--(*quit_counter) == 0) |
| 169 MessageLoop::current()->QuitWhenIdle(); | 101 MessageLoop::current()->QuitWhenIdle(); |
| 170 } | 102 } |
| 171 | 103 |
| 172 // This function records the time when Run was called in a Time object, which is | 104 // This function records the time when Run was called in a Time object, which is |
| 173 // useful for building a variety of MessageLoop tests. | 105 // useful for building a variety of MessageLoop tests. |
| 174 static void RecordRunTimeFunc(Time* run_time, int* quit_counter) { | 106 static void RecordRunTimeFunc(Time* run_time, int* quit_counter) { |
| 175 *run_time = Time::Now(); | 107 *run_time = Time::Now(); |
| 176 | 108 |
| 177 // Cause our Run function to take some time to execute. As a result we can | 109 // Cause our Run function to take some time to execute. As a result we can |
| 178 // count on subsequent RecordRunTimeFunc()s running at a future time, | 110 // count on subsequent RecordRunTimeFunc()s running at a future time, |
| 179 // without worry about the resolution of our system clock being an issue. | 111 // without worry about the resolution of our system clock being an issue. |
| 180 SlowFunc(TimeDelta::FromMilliseconds(10), quit_counter); | 112 SlowFunc(TimeDelta::FromMilliseconds(10), quit_counter); |
| 181 } | 113 } |
| 182 | 114 |
| 183 void RunTest_PostDelayedTask_Basic(MessageLoop::Type message_loop_type) { | |
| 184 MessageLoop loop(message_loop_type); | |
| 185 | |
| 186 // Test that PostDelayedTask results in a delayed task. | |
| 187 | |
| 188 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); | |
| 189 | |
| 190 int num_tasks = 1; | |
| 191 Time run_time; | |
| 192 | |
| 193 loop.PostDelayedTask( | |
| 194 FROM_HERE, Bind(&RecordRunTimeFunc, &run_time, &num_tasks), | |
| 195 kDelay); | |
| 196 | |
| 197 Time time_before_run = Time::Now(); | |
| 198 loop.Run(); | |
| 199 Time time_after_run = Time::Now(); | |
| 200 | |
| 201 EXPECT_EQ(0, num_tasks); | |
| 202 EXPECT_LT(kDelay, time_after_run - time_before_run); | |
| 203 } | |
| 204 | |
| 205 void RunTest_PostDelayedTask_InDelayOrder( | |
| 206 MessageLoop::Type message_loop_type) { | |
| 207 MessageLoop loop(message_loop_type); | |
| 208 | |
| 209 // Test that two tasks with different delays run in the right order. | |
| 210 int num_tasks = 2; | |
| 211 Time run_time1, run_time2; | |
| 212 | |
| 213 loop.PostDelayedTask( | |
| 214 FROM_HERE, | |
| 215 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), | |
| 216 TimeDelta::FromMilliseconds(200)); | |
| 217 // If we get a large pause in execution (due to a context switch) here, this | |
| 218 // test could fail. | |
| 219 loop.PostDelayedTask( | |
| 220 FROM_HERE, | |
| 221 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | |
| 222 TimeDelta::FromMilliseconds(10)); | |
| 223 | |
| 224 loop.Run(); | |
| 225 EXPECT_EQ(0, num_tasks); | |
| 226 | |
| 227 EXPECT_TRUE(run_time2 < run_time1); | |
| 228 } | |
| 229 | |
| 230 void RunTest_PostDelayedTask_InPostOrder( | |
| 231 MessageLoop::Type message_loop_type) { | |
| 232 MessageLoop loop(message_loop_type); | |
| 233 | |
| 234 // Test that two tasks with the same delay run in the order in which they | |
| 235 // were posted. | |
| 236 // | |
| 237 // NOTE: This is actually an approximate test since the API only takes a | |
| 238 // "delay" parameter, so we are not exactly simulating two tasks that get | |
| 239 // posted at the exact same time. It would be nice if the API allowed us to | |
| 240 // specify the desired run time. | |
| 241 | |
| 242 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); | |
| 243 | |
| 244 int num_tasks = 2; | |
| 245 Time run_time1, run_time2; | |
| 246 | |
| 247 loop.PostDelayedTask( | |
| 248 FROM_HERE, | |
| 249 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), kDelay); | |
| 250 loop.PostDelayedTask( | |
| 251 FROM_HERE, | |
| 252 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), kDelay); | |
| 253 | |
| 254 loop.Run(); | |
| 255 EXPECT_EQ(0, num_tasks); | |
| 256 | |
| 257 EXPECT_TRUE(run_time1 < run_time2); | |
| 258 } | |
| 259 | |
| 260 void RunTest_PostDelayedTask_InPostOrder_2( | |
| 261 MessageLoop::Type message_loop_type) { | |
| 262 MessageLoop loop(message_loop_type); | |
| 263 | |
| 264 // Test that a delayed task still runs after a normal tasks even if the | |
| 265 // normal tasks take a long time to run. | |
| 266 | |
| 267 const TimeDelta kPause = TimeDelta::FromMilliseconds(50); | |
| 268 | |
| 269 int num_tasks = 2; | |
| 270 Time run_time; | |
| 271 | |
| 272 loop.PostTask(FROM_HERE, Bind(&SlowFunc, kPause, &num_tasks)); | |
| 273 loop.PostDelayedTask( | |
| 274 FROM_HERE, | |
| 275 Bind(&RecordRunTimeFunc, &run_time, &num_tasks), | |
| 276 TimeDelta::FromMilliseconds(10)); | |
| 277 | |
| 278 Time time_before_run = Time::Now(); | |
| 279 loop.Run(); | |
| 280 Time time_after_run = Time::Now(); | |
| 281 | |
| 282 EXPECT_EQ(0, num_tasks); | |
| 283 | |
| 284 EXPECT_LT(kPause, time_after_run - time_before_run); | |
| 285 } | |
| 286 | |
| 287 void RunTest_PostDelayedTask_InPostOrder_3( | |
| 288 MessageLoop::Type message_loop_type) { | |
| 289 MessageLoop loop(message_loop_type); | |
| 290 | |
| 291 // Test that a delayed task still runs after a pile of normal tasks. The key | |
| 292 // difference between this test and the previous one is that here we return | |
| 293 // the MessageLoop a lot so we give the MessageLoop plenty of opportunities | |
| 294 // to maybe run the delayed task. It should know not to do so until the | |
| 295 // delayed task's delay has passed. | |
| 296 | |
| 297 int num_tasks = 11; | |
| 298 Time run_time1, run_time2; | |
| 299 | |
| 300 // Clutter the ML with tasks. | |
| 301 for (int i = 1; i < num_tasks; ++i) | |
| 302 loop.PostTask(FROM_HERE, | |
| 303 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks)); | |
| 304 | |
| 305 loop.PostDelayedTask( | |
| 306 FROM_HERE, Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | |
| 307 TimeDelta::FromMilliseconds(1)); | |
| 308 | |
| 309 loop.Run(); | |
| 310 EXPECT_EQ(0, num_tasks); | |
| 311 | |
| 312 EXPECT_TRUE(run_time2 > run_time1); | |
| 313 } | |
| 314 | |
| 315 void RunTest_PostDelayedTask_SharedTimer( | |
| 316 MessageLoop::Type message_loop_type) { | |
| 317 MessageLoop loop(message_loop_type); | |
| 318 | |
| 319 // Test that the interval of the timer, used to run the next delayed task, is | |
| 320 // set to a value corresponding to when the next delayed task should run. | |
| 321 | |
| 322 // By setting num_tasks to 1, we ensure that the first task to run causes the | |
| 323 // run loop to exit. | |
| 324 int num_tasks = 1; | |
| 325 Time run_time1, run_time2; | |
| 326 | |
| 327 loop.PostDelayedTask( | |
| 328 FROM_HERE, | |
| 329 Bind(&RecordRunTimeFunc, &run_time1, &num_tasks), | |
| 330 TimeDelta::FromSeconds(1000)); | |
| 331 loop.PostDelayedTask( | |
| 332 FROM_HERE, | |
| 333 Bind(&RecordRunTimeFunc, &run_time2, &num_tasks), | |
| 334 TimeDelta::FromMilliseconds(10)); | |
| 335 | |
| 336 Time start_time = Time::Now(); | |
| 337 | |
| 338 loop.Run(); | |
| 339 EXPECT_EQ(0, num_tasks); | |
| 340 | |
| 341 // Ensure that we ran in far less time than the slower timer. | |
| 342 TimeDelta total_time = Time::Now() - start_time; | |
| 343 EXPECT_GT(5000, total_time.InMilliseconds()); | |
| 344 | |
| 345 // In case both timers somehow run at nearly the same time, sleep a little | |
| 346 // and then run all pending to force them both to have run. This is just | |
| 347 // encouraging flakiness if there is any. | |
| 348 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); | |
| 349 RunLoop().RunUntilIdle(); | |
| 350 | |
| 351 EXPECT_TRUE(run_time1.is_null()); | |
| 352 EXPECT_FALSE(run_time2.is_null()); | |
| 353 } | |
| 354 | |
| 355 #if defined(OS_WIN) | |
| 356 | |
| 357 void SubPumpFunc() { | 115 void SubPumpFunc() { |
| 358 MessageLoop::current()->SetNestableTasksAllowed(true); | 116 MessageLoop::current()->SetNestableTasksAllowed(true); |
| 359 MSG msg; | 117 MSG msg; |
| 360 while (GetMessage(&msg, NULL, 0, 0)) { | 118 while (GetMessage(&msg, NULL, 0, 0)) { |
| 361 TranslateMessage(&msg); | 119 TranslateMessage(&msg); |
| 362 DispatchMessage(&msg); | 120 DispatchMessage(&msg); |
| 363 } | 121 } |
| 364 MessageLoop::current()->QuitWhenIdle(); | 122 MessageLoop::current()->QuitWhenIdle(); |
| 365 } | 123 } |
| 366 | 124 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 | 158 |
| 401 // In case both timers somehow run at nearly the same time, sleep a little | 159 // In case both timers somehow run at nearly the same time, sleep a little |
| 402 // and then run all pending to force them both to have run. This is just | 160 // and then run all pending to force them both to have run. This is just |
| 403 // encouraging flakiness if there is any. | 161 // encouraging flakiness if there is any. |
| 404 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); | 162 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); |
| 405 RunLoop().RunUntilIdle(); | 163 RunLoop().RunUntilIdle(); |
| 406 | 164 |
| 407 EXPECT_TRUE(run_time.is_null()); | 165 EXPECT_TRUE(run_time.is_null()); |
| 408 } | 166 } |
| 409 | 167 |
| 410 #endif // defined(OS_WIN) | |
| 411 | |
| 412 // This is used to inject a test point for recording the destructor calls for | |
| 413 // Closure objects send to MessageLoop::PostTask(). It is awkward usage since we | |
| 414 // are trying to hook the actual destruction, which is not a common operation. | |
| 415 class RecordDeletionProbe : public RefCounted<RecordDeletionProbe> { | |
| 416 public: | |
| 417 RecordDeletionProbe(RecordDeletionProbe* post_on_delete, bool* was_deleted) | |
| 418 : post_on_delete_(post_on_delete), was_deleted_(was_deleted) { | |
| 419 } | |
| 420 void Run() {} | |
| 421 | |
| 422 private: | |
| 423 friend class RefCounted<RecordDeletionProbe>; | |
| 424 | |
| 425 ~RecordDeletionProbe() { | |
| 426 *was_deleted_ = true; | |
| 427 if (post_on_delete_.get()) | |
| 428 MessageLoop::current()->PostTask( | |
| 429 FROM_HERE, Bind(&RecordDeletionProbe::Run, post_on_delete_.get())); | |
| 430 } | |
| 431 | |
| 432 scoped_refptr<RecordDeletionProbe> post_on_delete_; | |
| 433 bool* was_deleted_; | |
| 434 }; | |
| 435 | |
| 436 void RunTest_EnsureDeletion(MessageLoop::Type message_loop_type) { | |
| 437 bool a_was_deleted = false; | |
| 438 bool b_was_deleted = false; | |
| 439 { | |
| 440 MessageLoop loop(message_loop_type); | |
| 441 loop.PostTask( | |
| 442 FROM_HERE, Bind(&RecordDeletionProbe::Run, | |
| 443 new RecordDeletionProbe(NULL, &a_was_deleted))); | |
| 444 // TODO(ajwong): Do we really need 1000ms here? | |
| 445 loop.PostDelayedTask( | |
| 446 FROM_HERE, Bind(&RecordDeletionProbe::Run, | |
| 447 new RecordDeletionProbe(NULL, &b_was_deleted)), | |
| 448 TimeDelta::FromMilliseconds(1000)); | |
| 449 } | |
| 450 EXPECT_TRUE(a_was_deleted); | |
| 451 EXPECT_TRUE(b_was_deleted); | |
| 452 } | |
| 453 | |
| 454 void RunTest_EnsureDeletion_Chain(MessageLoop::Type message_loop_type) { | |
| 455 bool a_was_deleted = false; | |
| 456 bool b_was_deleted = false; | |
| 457 bool c_was_deleted = false; | |
| 458 { | |
| 459 MessageLoop loop(message_loop_type); | |
| 460 // The scoped_refptr for each of the below is held either by the chained | |
| 461 // RecordDeletionProbe, or the bound RecordDeletionProbe::Run() callback. | |
| 462 RecordDeletionProbe* a = new RecordDeletionProbe(NULL, &a_was_deleted); | |
| 463 RecordDeletionProbe* b = new RecordDeletionProbe(a, &b_was_deleted); | |
| 464 RecordDeletionProbe* c = new RecordDeletionProbe(b, &c_was_deleted); | |
| 465 loop.PostTask(FROM_HERE, Bind(&RecordDeletionProbe::Run, c)); | |
| 466 } | |
| 467 EXPECT_TRUE(a_was_deleted); | |
| 468 EXPECT_TRUE(b_was_deleted); | |
| 469 EXPECT_TRUE(c_was_deleted); | |
| 470 } | |
| 471 | |
| 472 void NestingFunc(int* depth) { | |
| 473 if (*depth > 0) { | |
| 474 *depth -= 1; | |
| 475 MessageLoop::current()->PostTask(FROM_HERE, | |
| 476 Bind(&NestingFunc, depth)); | |
| 477 | |
| 478 MessageLoop::current()->SetNestableTasksAllowed(true); | |
| 479 MessageLoop::current()->Run(); | |
| 480 } | |
| 481 MessageLoop::current()->QuitWhenIdle(); | |
| 482 } | |
| 483 | |
| 484 #if defined(OS_WIN) | |
| 485 | |
| 486 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) { | 168 LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) { |
| 487 ADD_FAILURE() << "bad exception handler"; | 169 ADD_FAILURE() << "bad exception handler"; |
| 488 ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode); | 170 ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode); |
| 489 return EXCEPTION_EXECUTE_HANDLER; | 171 return EXCEPTION_EXECUTE_HANDLER; |
| 490 } | 172 } |
| 491 | 173 |
| 492 // This task throws an SEH exception: initially write to an invalid address. | 174 // This task throws an SEH exception: initially write to an invalid address. |
| 493 // If the right SEH filter is installed, it will fix the error. | 175 // If the right SEH filter is installed, it will fix the error. |
| 494 class Crasher : public RefCounted<Crasher> { | 176 class Crasher : public RefCounted<Crasher> { |
| 495 public: | 177 public: |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 MessageLoop::current()->PostTask( | 272 MessageLoop::current()->PostTask( |
| 591 FROM_HERE, | 273 FROM_HERE, |
| 592 Bind(&Crasher::Run, new Crasher(true))); | 274 Bind(&Crasher::Run, new Crasher(true))); |
| 593 MessageLoop::current()->set_exception_restoration(true); | 275 MessageLoop::current()->set_exception_restoration(true); |
| 594 MessageLoop::current()->Run(); | 276 MessageLoop::current()->Run(); |
| 595 MessageLoop::current()->set_exception_restoration(false); | 277 MessageLoop::current()->set_exception_restoration(false); |
| 596 | 278 |
| 597 ::SetUnhandledExceptionFilter(old_SEH_filter); | 279 ::SetUnhandledExceptionFilter(old_SEH_filter); |
| 598 } | 280 } |
| 599 | 281 |
| 600 #endif // defined(OS_WIN) | |
| 601 | |
| 602 void RunTest_Nesting(MessageLoop::Type message_loop_type) { | |
| 603 MessageLoop loop(message_loop_type); | |
| 604 | |
| 605 int depth = 100; | |
| 606 MessageLoop::current()->PostTask(FROM_HERE, | |
| 607 Bind(&NestingFunc, &depth)); | |
| 608 MessageLoop::current()->Run(); | |
| 609 EXPECT_EQ(depth, 0); | |
| 610 } | |
| 611 | |
| 612 #if defined(OS_WIN) | |
| 613 const wchar_t kMessageBoxTitle[] = L"MessageLoop Unit Test"; | 282 const wchar_t kMessageBoxTitle[] = L"MessageLoop Unit Test"; |
| 614 #endif // defined(OS_WIN) | |
| 615 | 283 |
| 616 enum TaskType { | 284 enum TaskType { |
| 617 MESSAGEBOX, | 285 MESSAGEBOX, |
| 618 ENDDIALOG, | 286 ENDDIALOG, |
| 619 RECURSIVE, | 287 RECURSIVE, |
| 620 TIMEDMESSAGELOOP, | 288 TIMEDMESSAGELOOP, |
| 621 QUITMESSAGELOOP, | 289 QUITMESSAGELOOP, |
| 622 ORDERED, | 290 ORDERED, |
| 623 PUMPS, | 291 PUMPS, |
| 624 SLEEP, | 292 SLEEP, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 } | 354 } |
| 687 | 355 |
| 688 TaskItem Get(int n) { | 356 TaskItem Get(int n) { |
| 689 return task_list_[n]; | 357 return task_list_[n]; |
| 690 } | 358 } |
| 691 | 359 |
| 692 private: | 360 private: |
| 693 std::vector<TaskItem> task_list_; | 361 std::vector<TaskItem> task_list_; |
| 694 }; | 362 }; |
| 695 | 363 |
| 696 // Saves the order the tasks ran. | |
| 697 void OrderedFunc(TaskList* order, int cookie) { | |
| 698 order->RecordStart(ORDERED, cookie); | |
| 699 order->RecordEnd(ORDERED, cookie); | |
| 700 } | |
| 701 | |
| 702 #if defined(OS_WIN) | |
| 703 | |
| 704 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes, | 364 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes, |
| 705 // common controls (like OpenFile) and StartDoc printing function can cause | 365 // common controls (like OpenFile) and StartDoc printing function can cause |
| 706 // implicit message loops. | 366 // implicit message loops. |
| 707 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) { | 367 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) { |
| 708 order->RecordStart(MESSAGEBOX, cookie); | 368 order->RecordStart(MESSAGEBOX, cookie); |
| 709 if (is_reentrant) | 369 if (is_reentrant) |
| 710 MessageLoop::current()->SetNestableTasksAllowed(true); | 370 MessageLoop::current()->SetNestableTasksAllowed(true); |
| 711 MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK); | 371 MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK); |
| 712 order->RecordEnd(MESSAGEBOX, cookie); | 372 order->RecordEnd(MESSAGEBOX, cookie); |
| 713 } | 373 } |
| 714 | 374 |
| 715 // Will end the MessageBox. | 375 // Will end the MessageBox. |
| 716 void EndDialogFunc(TaskList* order, int cookie) { | 376 void EndDialogFunc(TaskList* order, int cookie) { |
| 717 order->RecordStart(ENDDIALOG, cookie); | 377 order->RecordStart(ENDDIALOG, cookie); |
| 718 HWND window = GetActiveWindow(); | 378 HWND window = GetActiveWindow(); |
| 719 if (window != NULL) { | 379 if (window != NULL) { |
| 720 EXPECT_NE(EndDialog(window, IDCONTINUE), 0); | 380 EXPECT_NE(EndDialog(window, IDCONTINUE), 0); |
| 721 // Cheap way to signal that the window wasn't found if RunEnd() isn't | 381 // Cheap way to signal that the window wasn't found if RunEnd() isn't |
| 722 // called. | 382 // called. |
| 723 order->RecordEnd(ENDDIALOG, cookie); | 383 order->RecordEnd(ENDDIALOG, cookie); |
| 724 } | 384 } |
| 725 } | 385 } |
| 726 | 386 |
| 727 #endif // defined(OS_WIN) | |
| 728 | |
| 729 void RecursiveFunc(TaskList* order, int cookie, int depth, | 387 void RecursiveFunc(TaskList* order, int cookie, int depth, |
| 730 bool is_reentrant) { | 388 bool is_reentrant) { |
| 731 order->RecordStart(RECURSIVE, cookie); | 389 order->RecordStart(RECURSIVE, cookie); |
| 732 if (depth > 0) { | 390 if (depth > 0) { |
| 733 if (is_reentrant) | 391 if (is_reentrant) |
| 734 MessageLoop::current()->SetNestableTasksAllowed(true); | 392 MessageLoop::current()->SetNestableTasksAllowed(true); |
| 735 MessageLoop::current()->PostTask( | 393 MessageLoop::current()->PostTask( |
| 736 FROM_HERE, | 394 FROM_HERE, |
| 737 Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant)); | 395 Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant)); |
| 738 } | 396 } |
| 739 order->RecordEnd(RECURSIVE, cookie); | 397 order->RecordEnd(RECURSIVE, cookie); |
| 740 } | 398 } |
| 741 | 399 |
| 742 void RecursiveSlowFunc(TaskList* order, int cookie, int depth, | |
| 743 bool is_reentrant) { | |
| 744 RecursiveFunc(order, cookie, depth, is_reentrant); | |
| 745 PlatformThread::Sleep(TimeDelta::FromMilliseconds(10)); | |
| 746 } | |
| 747 | |
| 748 void QuitFunc(TaskList* order, int cookie) { | 400 void QuitFunc(TaskList* order, int cookie) { |
| 749 order->RecordStart(QUITMESSAGELOOP, cookie); | 401 order->RecordStart(QUITMESSAGELOOP, cookie); |
| 750 MessageLoop::current()->QuitWhenIdle(); | 402 MessageLoop::current()->QuitWhenIdle(); |
| 751 order->RecordEnd(QUITMESSAGELOOP, cookie); | 403 order->RecordEnd(QUITMESSAGELOOP, cookie); |
| 752 } | 404 } |
| 753 | 405 |
| 754 void SleepFunc(TaskList* order, int cookie, TimeDelta delay) { | |
| 755 order->RecordStart(SLEEP, cookie); | |
| 756 PlatformThread::Sleep(delay); | |
| 757 order->RecordEnd(SLEEP, cookie); | |
| 758 } | |
| 759 | |
| 760 #if defined(OS_WIN) | |
| 761 void RecursiveFuncWin(MessageLoop* target, | 406 void RecursiveFuncWin(MessageLoop* target, |
| 762 HANDLE event, | 407 HANDLE event, |
| 763 bool expect_window, | 408 bool expect_window, |
| 764 TaskList* order, | 409 TaskList* order, |
| 765 bool is_reentrant) { | 410 bool is_reentrant) { |
| 766 target->PostTask(FROM_HERE, | 411 target->PostTask(FROM_HERE, |
| 767 Bind(&RecursiveFunc, order, 1, 2, is_reentrant)); | 412 Bind(&RecursiveFunc, order, 1, 2, is_reentrant)); |
| 768 target->PostTask(FROM_HERE, | 413 target->PostTask(FROM_HERE, |
| 769 Bind(&MessageBoxFunc, order, 2, is_reentrant)); | 414 Bind(&MessageBoxFunc, order, 2, is_reentrant)); |
| 770 target->PostTask(FROM_HERE, | 415 target->PostTask(FROM_HERE, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 796 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0)); | 441 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0)); |
| 797 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0)); | 442 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0)); |
| 798 break; | 443 break; |
| 799 } | 444 } |
| 800 } | 445 } |
| 801 break; | 446 break; |
| 802 } | 447 } |
| 803 } | 448 } |
| 804 } | 449 } |
| 805 | 450 |
| 806 #endif // defined(OS_WIN) | |
| 807 | |
| 808 void RunTest_RecursiveDenial1(MessageLoop::Type message_loop_type) { | |
| 809 MessageLoop loop(message_loop_type); | |
| 810 | |
| 811 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); | |
| 812 TaskList order; | |
| 813 MessageLoop::current()->PostTask( | |
| 814 FROM_HERE, | |
| 815 Bind(&RecursiveFunc, &order, 1, 2, false)); | |
| 816 MessageLoop::current()->PostTask( | |
| 817 FROM_HERE, | |
| 818 Bind(&RecursiveFunc, &order, 2, 2, false)); | |
| 819 MessageLoop::current()->PostTask( | |
| 820 FROM_HERE, | |
| 821 Bind(&QuitFunc, &order, 3)); | |
| 822 | |
| 823 MessageLoop::current()->Run(); | |
| 824 | |
| 825 // FIFO order. | |
| 826 ASSERT_EQ(14U, order.Size()); | |
| 827 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | |
| 828 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | |
| 829 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | |
| 830 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | |
| 831 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | |
| 832 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); | |
| 833 EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true)); | |
| 834 EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false)); | |
| 835 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); | |
| 836 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); | |
| 837 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); | |
| 838 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); | |
| 839 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true)); | |
| 840 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false)); | |
| 841 } | |
| 842 | |
| 843 void RunTest_RecursiveDenial3(MessageLoop::Type message_loop_type) { | |
| 844 MessageLoop loop(message_loop_type); | |
| 845 | |
| 846 EXPECT_TRUE(MessageLoop::current()->NestableTasksAllowed()); | |
| 847 TaskList order; | |
| 848 MessageLoop::current()->PostTask( | |
| 849 FROM_HERE, Bind(&RecursiveSlowFunc, &order, 1, 2, false)); | |
| 850 MessageLoop::current()->PostTask( | |
| 851 FROM_HERE, Bind(&RecursiveSlowFunc, &order, 2, 2, false)); | |
| 852 MessageLoop::current()->PostDelayedTask( | |
| 853 FROM_HERE, | |
| 854 Bind(&OrderedFunc, &order, 3), | |
| 855 TimeDelta::FromMilliseconds(5)); | |
| 856 MessageLoop::current()->PostDelayedTask( | |
| 857 FROM_HERE, | |
| 858 Bind(&QuitFunc, &order, 4), | |
| 859 TimeDelta::FromMilliseconds(5)); | |
| 860 | |
| 861 MessageLoop::current()->Run(); | |
| 862 | |
| 863 // FIFO order. | |
| 864 ASSERT_EQ(16U, order.Size()); | |
| 865 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | |
| 866 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | |
| 867 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | |
| 868 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | |
| 869 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 1, true)); | |
| 870 EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 1, false)); | |
| 871 EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 3, true)); | |
| 872 EXPECT_EQ(order.Get(7), TaskItem(ORDERED, 3, false)); | |
| 873 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); | |
| 874 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); | |
| 875 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 4, true)); | |
| 876 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 4, false)); | |
| 877 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 1, true)); | |
| 878 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, false)); | |
| 879 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 2, true)); | |
| 880 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 2, false)); | |
| 881 } | |
| 882 | |
| 883 void RunTest_RecursiveSupport1(MessageLoop::Type message_loop_type) { | |
| 884 MessageLoop loop(message_loop_type); | |
| 885 | |
| 886 TaskList order; | |
| 887 MessageLoop::current()->PostTask( | |
| 888 FROM_HERE, Bind(&RecursiveFunc, &order, 1, 2, true)); | |
| 889 MessageLoop::current()->PostTask( | |
| 890 FROM_HERE, Bind(&RecursiveFunc, &order, 2, 2, true)); | |
| 891 MessageLoop::current()->PostTask( | |
| 892 FROM_HERE, Bind(&QuitFunc, &order, 3)); | |
| 893 | |
| 894 MessageLoop::current()->Run(); | |
| 895 | |
| 896 // FIFO order. | |
| 897 ASSERT_EQ(14U, order.Size()); | |
| 898 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); | |
| 899 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); | |
| 900 EXPECT_EQ(order.Get(2), TaskItem(RECURSIVE, 2, true)); | |
| 901 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 2, false)); | |
| 902 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | |
| 903 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); | |
| 904 EXPECT_EQ(order.Get(6), TaskItem(RECURSIVE, 1, true)); | |
| 905 EXPECT_EQ(order.Get(7), TaskItem(RECURSIVE, 1, false)); | |
| 906 EXPECT_EQ(order.Get(8), TaskItem(RECURSIVE, 2, true)); | |
| 907 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 2, false)); | |
| 908 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); | |
| 909 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); | |
| 910 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 2, true)); | |
| 911 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 2, false)); | |
| 912 } | |
| 913 | |
| 914 #if defined(OS_WIN) | |
| 915 // TODO(darin): These tests need to be ported since they test critical | 451 // TODO(darin): These tests need to be ported since they test critical |
| 916 // message loop functionality. | 452 // message loop functionality. |
| 917 | 453 |
| 918 // A side effect of this test is the generation a beep. Sorry. | 454 // A side effect of this test is the generation a beep. Sorry. |
| 919 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { | 455 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { |
| 920 MessageLoop loop(message_loop_type); | 456 MessageLoop loop(message_loop_type); |
| 921 | 457 |
| 922 Thread worker("RecursiveDenial2_worker"); | 458 Thread worker("RecursiveDenial2_worker"); |
| 923 Thread::Options options; | 459 Thread::Options options; |
| 924 options.message_loop_type = message_loop_type; | 460 options.message_loop_type = message_loop_type; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true)); | 538 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true)); |
| 1003 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false)); | 539 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false)); |
| 1004 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true)); | 540 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true)); |
| 1005 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false)); | 541 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false)); |
| 1006 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true)); | 542 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true)); |
| 1007 EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false)); | 543 EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false)); |
| 1008 } | 544 } |
| 1009 | 545 |
| 1010 #endif // defined(OS_WIN) | 546 #endif // defined(OS_WIN) |
| 1011 | 547 |
| 1012 void FuncThatPumps(TaskList* order, int cookie) { | |
| 1013 order->RecordStart(PUMPS, cookie); | |
| 1014 { | |
| 1015 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); | |
| 1016 RunLoop().RunUntilIdle(); | |
| 1017 } | |
| 1018 order->RecordEnd(PUMPS, cookie); | |
| 1019 } | |
| 1020 | |
| 1021 void FuncThatRuns(TaskList* order, int cookie, RunLoop* run_loop) { | |
| 1022 order->RecordStart(RUNS, cookie); | |
| 1023 { | |
| 1024 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); | |
| 1025 run_loop->Run(); | |
| 1026 } | |
| 1027 order->RecordEnd(RUNS, cookie); | |
| 1028 } | |
| 1029 | |
| 1030 void FuncThatQuitsNow() { | |
| 1031 MessageLoop::current()->QuitNow(); | |
| 1032 } | |
| 1033 | |
| 1034 // Tests that non nestable tasks run in FIFO if there are no nested loops. | |
| 1035 void RunTest_NonNestableWithNoNesting( | |
| 1036 MessageLoop::Type message_loop_type) { | |
| 1037 MessageLoop loop(message_loop_type); | |
| 1038 | |
| 1039 TaskList order; | |
| 1040 | |
| 1041 MessageLoop::current()->PostNonNestableTask( | |
| 1042 FROM_HERE, | |
| 1043 Bind(&OrderedFunc, &order, 1)); | |
| 1044 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1045 Bind(&OrderedFunc, &order, 2)); | |
| 1046 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1047 Bind(&QuitFunc, &order, 3)); | |
| 1048 MessageLoop::current()->Run(); | |
| 1049 | |
| 1050 // FIFO order. | |
| 1051 ASSERT_EQ(6U, order.Size()); | |
| 1052 EXPECT_EQ(order.Get(0), TaskItem(ORDERED, 1, true)); | |
| 1053 EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 1, false)); | |
| 1054 EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 2, true)); | |
| 1055 EXPECT_EQ(order.Get(3), TaskItem(ORDERED, 2, false)); | |
| 1056 EXPECT_EQ(order.Get(4), TaskItem(QUITMESSAGELOOP, 3, true)); | |
| 1057 EXPECT_EQ(order.Get(5), TaskItem(QUITMESSAGELOOP, 3, false)); | |
| 1058 } | |
| 1059 | |
| 1060 // Tests that non nestable tasks don't run when there's code in the call stack. | |
| 1061 void RunTest_NonNestableInNestedLoop(MessageLoop::Type message_loop_type, | |
| 1062 bool use_delayed) { | |
| 1063 MessageLoop loop(message_loop_type); | |
| 1064 | |
| 1065 TaskList order; | |
| 1066 | |
| 1067 MessageLoop::current()->PostTask( | |
| 1068 FROM_HERE, | |
| 1069 Bind(&FuncThatPumps, &order, 1)); | |
| 1070 if (use_delayed) { | |
| 1071 MessageLoop::current()->PostNonNestableDelayedTask( | |
| 1072 FROM_HERE, | |
| 1073 Bind(&OrderedFunc, &order, 2), | |
| 1074 TimeDelta::FromMilliseconds(1)); | |
| 1075 } else { | |
| 1076 MessageLoop::current()->PostNonNestableTask( | |
| 1077 FROM_HERE, | |
| 1078 Bind(&OrderedFunc, &order, 2)); | |
| 1079 } | |
| 1080 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1081 Bind(&OrderedFunc, &order, 3)); | |
| 1082 MessageLoop::current()->PostTask( | |
| 1083 FROM_HERE, | |
| 1084 Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50))); | |
| 1085 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1086 Bind(&OrderedFunc, &order, 5)); | |
| 1087 if (use_delayed) { | |
| 1088 MessageLoop::current()->PostNonNestableDelayedTask( | |
| 1089 FROM_HERE, | |
| 1090 Bind(&QuitFunc, &order, 6), | |
| 1091 TimeDelta::FromMilliseconds(2)); | |
| 1092 } else { | |
| 1093 MessageLoop::current()->PostNonNestableTask( | |
| 1094 FROM_HERE, | |
| 1095 Bind(&QuitFunc, &order, 6)); | |
| 1096 } | |
| 1097 | |
| 1098 MessageLoop::current()->Run(); | |
| 1099 | |
| 1100 // FIFO order. | |
| 1101 ASSERT_EQ(12U, order.Size()); | |
| 1102 EXPECT_EQ(order.Get(0), TaskItem(PUMPS, 1, true)); | |
| 1103 EXPECT_EQ(order.Get(1), TaskItem(ORDERED, 3, true)); | |
| 1104 EXPECT_EQ(order.Get(2), TaskItem(ORDERED, 3, false)); | |
| 1105 EXPECT_EQ(order.Get(3), TaskItem(SLEEP, 4, true)); | |
| 1106 EXPECT_EQ(order.Get(4), TaskItem(SLEEP, 4, false)); | |
| 1107 EXPECT_EQ(order.Get(5), TaskItem(ORDERED, 5, true)); | |
| 1108 EXPECT_EQ(order.Get(6), TaskItem(ORDERED, 5, false)); | |
| 1109 EXPECT_EQ(order.Get(7), TaskItem(PUMPS, 1, false)); | |
| 1110 EXPECT_EQ(order.Get(8), TaskItem(ORDERED, 2, true)); | |
| 1111 EXPECT_EQ(order.Get(9), TaskItem(ORDERED, 2, false)); | |
| 1112 EXPECT_EQ(order.Get(10), TaskItem(QUITMESSAGELOOP, 6, true)); | |
| 1113 EXPECT_EQ(order.Get(11), TaskItem(QUITMESSAGELOOP, 6, false)); | |
| 1114 } | |
| 1115 | |
| 1116 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
| 1117 void RunTest_QuitNow(MessageLoop::Type message_loop_type) { | |
| 1118 MessageLoop loop(message_loop_type); | |
| 1119 | |
| 1120 TaskList order; | |
| 1121 | |
| 1122 RunLoop run_loop; | |
| 1123 | |
| 1124 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1125 Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop))); | |
| 1126 MessageLoop::current()->PostTask( | |
| 1127 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
| 1128 MessageLoop::current()->PostTask( | |
| 1129 FROM_HERE, Bind(&FuncThatQuitsNow)); | |
| 1130 MessageLoop::current()->PostTask( | |
| 1131 FROM_HERE, Bind(&OrderedFunc, &order, 3)); | |
| 1132 MessageLoop::current()->PostTask( | |
| 1133 FROM_HERE, Bind(&FuncThatQuitsNow)); | |
| 1134 MessageLoop::current()->PostTask( | |
| 1135 FROM_HERE, Bind(&OrderedFunc, &order, 4)); // never runs | |
| 1136 | |
| 1137 MessageLoop::current()->Run(); | |
| 1138 | |
| 1139 ASSERT_EQ(6U, order.Size()); | |
| 1140 int task_index = 0; | |
| 1141 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
| 1142 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
| 1143 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
| 1144 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
| 1145 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true)); | |
| 1146 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false)); | |
| 1147 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
| 1148 } | |
| 1149 | |
| 1150 // Tests RunLoopQuit works before RunWithID. | |
| 1151 void RunTest_RunLoopQuitOrderBefore(MessageLoop::Type message_loop_type) { | |
| 1152 MessageLoop loop(message_loop_type); | |
| 1153 | |
| 1154 TaskList order; | |
| 1155 | |
| 1156 RunLoop run_loop; | |
| 1157 | |
| 1158 run_loop.Quit(); | |
| 1159 | |
| 1160 MessageLoop::current()->PostTask( | |
| 1161 FROM_HERE, Bind(&OrderedFunc, &order, 1)); // never runs | |
| 1162 MessageLoop::current()->PostTask( | |
| 1163 FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs | |
| 1164 | |
| 1165 run_loop.Run(); | |
| 1166 | |
| 1167 ASSERT_EQ(0U, order.Size()); | |
| 1168 } | |
| 1169 | |
| 1170 // Tests RunLoopQuit works during RunWithID. | |
| 1171 void RunTest_RunLoopQuitOrderDuring(MessageLoop::Type message_loop_type) { | |
| 1172 MessageLoop loop(message_loop_type); | |
| 1173 | |
| 1174 TaskList order; | |
| 1175 | |
| 1176 RunLoop run_loop; | |
| 1177 | |
| 1178 MessageLoop::current()->PostTask( | |
| 1179 FROM_HERE, Bind(&OrderedFunc, &order, 1)); | |
| 1180 MessageLoop::current()->PostTask( | |
| 1181 FROM_HERE, run_loop.QuitClosure()); | |
| 1182 MessageLoop::current()->PostTask( | |
| 1183 FROM_HERE, Bind(&OrderedFunc, &order, 2)); // never runs | |
| 1184 MessageLoop::current()->PostTask( | |
| 1185 FROM_HERE, Bind(&FuncThatQuitsNow)); // never runs | |
| 1186 | |
| 1187 run_loop.Run(); | |
| 1188 | |
| 1189 ASSERT_EQ(2U, order.Size()); | |
| 1190 int task_index = 0; | |
| 1191 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, true)); | |
| 1192 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 1, false)); | |
| 1193 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
| 1194 } | |
| 1195 | |
| 1196 // Tests RunLoopQuit works after RunWithID. | |
| 1197 void RunTest_RunLoopQuitOrderAfter(MessageLoop::Type message_loop_type) { | |
| 1198 MessageLoop loop(message_loop_type); | |
| 1199 | |
| 1200 TaskList order; | |
| 1201 | |
| 1202 RunLoop run_loop; | |
| 1203 | |
| 1204 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1205 Bind(&FuncThatRuns, &order, 1, Unretained(&run_loop))); | |
| 1206 MessageLoop::current()->PostTask( | |
| 1207 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
| 1208 MessageLoop::current()->PostTask( | |
| 1209 FROM_HERE, Bind(&FuncThatQuitsNow)); | |
| 1210 MessageLoop::current()->PostTask( | |
| 1211 FROM_HERE, Bind(&OrderedFunc, &order, 3)); | |
| 1212 MessageLoop::current()->PostTask( | |
| 1213 FROM_HERE, run_loop.QuitClosure()); // has no affect | |
| 1214 MessageLoop::current()->PostTask( | |
| 1215 FROM_HERE, Bind(&OrderedFunc, &order, 4)); | |
| 1216 MessageLoop::current()->PostTask( | |
| 1217 FROM_HERE, Bind(&FuncThatQuitsNow)); | |
| 1218 | |
| 1219 RunLoop outer_run_loop; | |
| 1220 outer_run_loop.Run(); | |
| 1221 | |
| 1222 ASSERT_EQ(8U, order.Size()); | |
| 1223 int task_index = 0; | |
| 1224 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
| 1225 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
| 1226 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
| 1227 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
| 1228 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, true)); | |
| 1229 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 3, false)); | |
| 1230 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, true)); | |
| 1231 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 4, false)); | |
| 1232 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
| 1233 } | |
| 1234 | |
| 1235 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
| 1236 void RunTest_RunLoopQuitTop(MessageLoop::Type message_loop_type) { | |
| 1237 MessageLoop loop(message_loop_type); | |
| 1238 | |
| 1239 TaskList order; | |
| 1240 | |
| 1241 RunLoop outer_run_loop; | |
| 1242 RunLoop nested_run_loop; | |
| 1243 | |
| 1244 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1245 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); | |
| 1246 MessageLoop::current()->PostTask( | |
| 1247 FROM_HERE, outer_run_loop.QuitClosure()); | |
| 1248 MessageLoop::current()->PostTask( | |
| 1249 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
| 1250 MessageLoop::current()->PostTask( | |
| 1251 FROM_HERE, nested_run_loop.QuitClosure()); | |
| 1252 | |
| 1253 outer_run_loop.Run(); | |
| 1254 | |
| 1255 ASSERT_EQ(4U, order.Size()); | |
| 1256 int task_index = 0; | |
| 1257 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
| 1258 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
| 1259 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
| 1260 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
| 1261 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
| 1262 } | |
| 1263 | |
| 1264 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
| 1265 void RunTest_RunLoopQuitNested(MessageLoop::Type message_loop_type) { | |
| 1266 MessageLoop loop(message_loop_type); | |
| 1267 | |
| 1268 TaskList order; | |
| 1269 | |
| 1270 RunLoop outer_run_loop; | |
| 1271 RunLoop nested_run_loop; | |
| 1272 | |
| 1273 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1274 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); | |
| 1275 MessageLoop::current()->PostTask( | |
| 1276 FROM_HERE, nested_run_loop.QuitClosure()); | |
| 1277 MessageLoop::current()->PostTask( | |
| 1278 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
| 1279 MessageLoop::current()->PostTask( | |
| 1280 FROM_HERE, outer_run_loop.QuitClosure()); | |
| 1281 | |
| 1282 outer_run_loop.Run(); | |
| 1283 | |
| 1284 ASSERT_EQ(4U, order.Size()); | |
| 1285 int task_index = 0; | |
| 1286 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
| 1287 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
| 1288 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
| 1289 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
| 1290 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
| 1291 } | |
| 1292 | |
| 1293 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
| 1294 void RunTest_RunLoopQuitBogus(MessageLoop::Type message_loop_type) { | |
| 1295 MessageLoop loop(message_loop_type); | |
| 1296 | |
| 1297 TaskList order; | |
| 1298 | |
| 1299 RunLoop outer_run_loop; | |
| 1300 RunLoop nested_run_loop; | |
| 1301 RunLoop bogus_run_loop; | |
| 1302 | |
| 1303 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1304 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_run_loop))); | |
| 1305 MessageLoop::current()->PostTask( | |
| 1306 FROM_HERE, bogus_run_loop.QuitClosure()); | |
| 1307 MessageLoop::current()->PostTask( | |
| 1308 FROM_HERE, Bind(&OrderedFunc, &order, 2)); | |
| 1309 MessageLoop::current()->PostTask( | |
| 1310 FROM_HERE, outer_run_loop.QuitClosure()); | |
| 1311 MessageLoop::current()->PostTask( | |
| 1312 FROM_HERE, nested_run_loop.QuitClosure()); | |
| 1313 | |
| 1314 outer_run_loop.Run(); | |
| 1315 | |
| 1316 ASSERT_EQ(4U, order.Size()); | |
| 1317 int task_index = 0; | |
| 1318 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
| 1319 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, true)); | |
| 1320 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 2, false)); | |
| 1321 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
| 1322 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
| 1323 } | |
| 1324 | |
| 1325 // Tests RunLoopQuit only quits the corresponding MessageLoop::Run. | |
| 1326 void RunTest_RunLoopQuitDeep(MessageLoop::Type message_loop_type) { | |
| 1327 MessageLoop loop(message_loop_type); | |
| 1328 | |
| 1329 TaskList order; | |
| 1330 | |
| 1331 RunLoop outer_run_loop; | |
| 1332 RunLoop nested_loop1; | |
| 1333 RunLoop nested_loop2; | |
| 1334 RunLoop nested_loop3; | |
| 1335 RunLoop nested_loop4; | |
| 1336 | |
| 1337 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1338 Bind(&FuncThatRuns, &order, 1, Unretained(&nested_loop1))); | |
| 1339 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1340 Bind(&FuncThatRuns, &order, 2, Unretained(&nested_loop2))); | |
| 1341 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1342 Bind(&FuncThatRuns, &order, 3, Unretained(&nested_loop3))); | |
| 1343 MessageLoop::current()->PostTask(FROM_HERE, | |
| 1344 Bind(&FuncThatRuns, &order, 4, Unretained(&nested_loop4))); | |
| 1345 MessageLoop::current()->PostTask( | |
| 1346 FROM_HERE, Bind(&OrderedFunc, &order, 5)); | |
| 1347 MessageLoop::current()->PostTask( | |
| 1348 FROM_HERE, outer_run_loop.QuitClosure()); | |
| 1349 MessageLoop::current()->PostTask( | |
| 1350 FROM_HERE, Bind(&OrderedFunc, &order, 6)); | |
| 1351 MessageLoop::current()->PostTask( | |
| 1352 FROM_HERE, nested_loop1.QuitClosure()); | |
| 1353 MessageLoop::current()->PostTask( | |
| 1354 FROM_HERE, Bind(&OrderedFunc, &order, 7)); | |
| 1355 MessageLoop::current()->PostTask( | |
| 1356 FROM_HERE, nested_loop2.QuitClosure()); | |
| 1357 MessageLoop::current()->PostTask( | |
| 1358 FROM_HERE, Bind(&OrderedFunc, &order, 8)); | |
| 1359 MessageLoop::current()->PostTask( | |
| 1360 FROM_HERE, nested_loop3.QuitClosure()); | |
| 1361 MessageLoop::current()->PostTask( | |
| 1362 FROM_HERE, Bind(&OrderedFunc, &order, 9)); | |
| 1363 MessageLoop::current()->PostTask( | |
| 1364 FROM_HERE, nested_loop4.QuitClosure()); | |
| 1365 MessageLoop::current()->PostTask( | |
| 1366 FROM_HERE, Bind(&OrderedFunc, &order, 10)); | |
| 1367 | |
| 1368 outer_run_loop.Run(); | |
| 1369 | |
| 1370 ASSERT_EQ(18U, order.Size()); | |
| 1371 int task_index = 0; | |
| 1372 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, true)); | |
| 1373 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, true)); | |
| 1374 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, true)); | |
| 1375 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, true)); | |
| 1376 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, true)); | |
| 1377 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 5, false)); | |
| 1378 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 6, true)); | |
| 1379 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 6, false)); | |
| 1380 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 7, true)); | |
| 1381 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 7, false)); | |
| 1382 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 8, true)); | |
| 1383 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 8, false)); | |
| 1384 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 9, true)); | |
| 1385 EXPECT_EQ(order.Get(task_index++), TaskItem(ORDERED, 9, false)); | |
| 1386 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 4, false)); | |
| 1387 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 3, false)); | |
| 1388 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 2, false)); | |
| 1389 EXPECT_EQ(order.Get(task_index++), TaskItem(RUNS, 1, false)); | |
| 1390 EXPECT_EQ(static_cast<size_t>(task_index), order.Size()); | |
| 1391 } | |
| 1392 | |
| 1393 void PostNTasksThenQuit(int posts_remaining) { | 548 void PostNTasksThenQuit(int posts_remaining) { |
| 1394 if (posts_remaining > 1) { | 549 if (posts_remaining > 1) { |
| 1395 MessageLoop::current()->PostTask( | 550 MessageLoop::current()->PostTask( |
| 1396 FROM_HERE, | 551 FROM_HERE, |
| 1397 Bind(&PostNTasksThenQuit, posts_remaining - 1)); | 552 Bind(&PostNTasksThenQuit, posts_remaining - 1)); |
| 1398 } else { | 553 } else { |
| 1399 MessageLoop::current()->QuitWhenIdle(); | 554 MessageLoop::current()->QuitWhenIdle(); |
| 1400 } | 555 } |
| 1401 } | 556 } |
| 1402 | 557 |
| 1403 void RunTest_RecursivePosts(MessageLoop::Type message_loop_type, | |
| 1404 int num_times) { | |
| 1405 MessageLoop loop(message_loop_type); | |
| 1406 loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, num_times)); | |
| 1407 loop.Run(); | |
| 1408 } | |
| 1409 | |
| 1410 #if defined(OS_WIN) | 558 #if defined(OS_WIN) |
| 1411 | 559 |
| 1412 class DispatcherImpl : public MessageLoopForUI::Dispatcher { | 560 class DispatcherImpl : public MessageLoopForUI::Dispatcher { |
| 1413 public: | 561 public: |
| 1414 DispatcherImpl() : dispatch_count_(0) {} | 562 DispatcherImpl() : dispatch_count_(0) {} |
| 1415 | 563 |
| 1416 virtual bool Dispatch(const NativeEvent& msg) OVERRIDE { | 564 virtual bool Dispatch(const NativeEvent& msg) OVERRIDE { |
| 1417 ::TranslateMessage(&msg); | 565 ::TranslateMessage(&msg); |
| 1418 ::DispatchMessage(&msg); | 566 ::DispatchMessage(&msg); |
| 1419 // Do not count WM_TIMER since it is not what we post and it will cause | 567 // Do not count WM_TIMER since it is not what we post and it will cause |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1615 | 763 |
| 1616 #endif // defined(OS_WIN) | 764 #endif // defined(OS_WIN) |
| 1617 | 765 |
| 1618 } // namespace | 766 } // namespace |
| 1619 | 767 |
| 1620 //----------------------------------------------------------------------------- | 768 //----------------------------------------------------------------------------- |
| 1621 // Each test is run against each type of MessageLoop. That way we are sure | 769 // Each test is run against each type of MessageLoop. That way we are sure |
| 1622 // that message loops work properly in all configurations. Of course, in some | 770 // that message loops work properly in all configurations. Of course, in some |
| 1623 // cases, a unit test may only be for a particular type of loop. | 771 // cases, a unit test may only be for a particular type of loop. |
| 1624 | 772 |
| 1625 TEST(MessageLoopTest, PostTask) { | 773 RUN_MESSAGE_LOOP_TESTS(Default, &TypeDefaultMessagePumpFactory); |
| 1626 RunTest_PostTask(MessageLoop::TYPE_DEFAULT); | 774 RUN_MESSAGE_LOOP_TESTS(UI, &TypeUIMessagePumpFactory); |
| 1627 RunTest_PostTask(MessageLoop::TYPE_UI); | 775 RUN_MESSAGE_LOOP_TESTS(IO, &TypeIOMessagePumpFactory); |
| 1628 RunTest_PostTask(MessageLoop::TYPE_IO); | |
| 1629 } | |
| 1630 | |
| 1631 TEST(MessageLoopTest, PostTask_SEH) { | |
| 1632 RunTest_PostTask_SEH(MessageLoop::TYPE_DEFAULT); | |
| 1633 RunTest_PostTask_SEH(MessageLoop::TYPE_UI); | |
| 1634 RunTest_PostTask_SEH(MessageLoop::TYPE_IO); | |
| 1635 } | |
| 1636 | |
| 1637 TEST(MessageLoopTest, PostDelayedTask_Basic) { | |
| 1638 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_DEFAULT); | |
| 1639 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_UI); | |
| 1640 RunTest_PostDelayedTask_Basic(MessageLoop::TYPE_IO); | |
| 1641 } | |
| 1642 | |
| 1643 TEST(MessageLoopTest, PostDelayedTask_InDelayOrder) { | |
| 1644 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_DEFAULT); | |
| 1645 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_UI); | |
| 1646 RunTest_PostDelayedTask_InDelayOrder(MessageLoop::TYPE_IO); | |
| 1647 } | |
| 1648 | |
| 1649 TEST(MessageLoopTest, PostDelayedTask_InPostOrder) { | |
| 1650 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_DEFAULT); | |
| 1651 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_UI); | |
| 1652 RunTest_PostDelayedTask_InPostOrder(MessageLoop::TYPE_IO); | |
| 1653 } | |
| 1654 | |
| 1655 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_2) { | |
| 1656 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_DEFAULT); | |
| 1657 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_UI); | |
| 1658 RunTest_PostDelayedTask_InPostOrder_2(MessageLoop::TYPE_IO); | |
| 1659 } | |
| 1660 | |
| 1661 TEST(MessageLoopTest, PostDelayedTask_InPostOrder_3) { | |
| 1662 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_DEFAULT); | |
| 1663 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_UI); | |
| 1664 RunTest_PostDelayedTask_InPostOrder_3(MessageLoop::TYPE_IO); | |
| 1665 } | |
| 1666 | |
| 1667 TEST(MessageLoopTest, PostDelayedTask_SharedTimer) { | |
| 1668 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_DEFAULT); | |
| 1669 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_UI); | |
| 1670 RunTest_PostDelayedTask_SharedTimer(MessageLoop::TYPE_IO); | |
| 1671 } | |
| 1672 | 776 |
| 1673 #if defined(OS_WIN) | 777 #if defined(OS_WIN) |
| 1674 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) { | 778 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) { |
| 1675 RunTest_PostDelayedTask_SharedTimer_SubPump(); | 779 RunTest_PostDelayedTask_SharedTimer_SubPump(); |
| 1676 } | 780 } |
| 1677 #endif | |
| 1678 | 781 |
| 1679 // TODO(darin): MessageLoop does not support deleting all tasks in the | |
| 1680 // destructor. | |
| 1681 // Fails, http://crbug.com/50272. | |
| 1682 TEST(MessageLoopTest, DISABLED_EnsureDeletion) { | |
| 1683 RunTest_EnsureDeletion(MessageLoop::TYPE_DEFAULT); | |
| 1684 RunTest_EnsureDeletion(MessageLoop::TYPE_UI); | |
| 1685 RunTest_EnsureDeletion(MessageLoop::TYPE_IO); | |
| 1686 } | |
| 1687 | |
| 1688 // TODO(darin): MessageLoop does not support deleting all tasks in the | |
| 1689 // destructor. | |
| 1690 // Fails, http://crbug.com/50272. | |
| 1691 TEST(MessageLoopTest, DISABLED_EnsureDeletion_Chain) { | |
| 1692 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_DEFAULT); | |
| 1693 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_UI); | |
| 1694 RunTest_EnsureDeletion_Chain(MessageLoop::TYPE_IO); | |
| 1695 } | |
| 1696 | |
| 1697 #if defined(OS_WIN) | |
| 1698 TEST(MessageLoopTest, Crasher) { | 782 TEST(MessageLoopTest, Crasher) { |
| 1699 RunTest_Crasher(MessageLoop::TYPE_DEFAULT); | 783 RunTest_Crasher(MessageLoop::TYPE_DEFAULT); |
| 1700 RunTest_Crasher(MessageLoop::TYPE_UI); | 784 RunTest_Crasher(MessageLoop::TYPE_UI); |
| 1701 RunTest_Crasher(MessageLoop::TYPE_IO); | 785 RunTest_Crasher(MessageLoop::TYPE_IO); |
| 1702 } | 786 } |
| 1703 | 787 |
| 1704 TEST(MessageLoopTest, CrasherNasty) { | 788 TEST(MessageLoopTest, CrasherNasty) { |
| 1705 RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT); | 789 RunTest_CrasherNasty(MessageLoop::TYPE_DEFAULT); |
| 1706 RunTest_CrasherNasty(MessageLoop::TYPE_UI); | 790 RunTest_CrasherNasty(MessageLoop::TYPE_UI); |
| 1707 RunTest_CrasherNasty(MessageLoop::TYPE_IO); | 791 RunTest_CrasherNasty(MessageLoop::TYPE_IO); |
| 1708 } | 792 } |
| 1709 #endif // defined(OS_WIN) | |
| 1710 | 793 |
| 1711 TEST(MessageLoopTest, Nesting) { | |
| 1712 RunTest_Nesting(MessageLoop::TYPE_DEFAULT); | |
| 1713 RunTest_Nesting(MessageLoop::TYPE_UI); | |
| 1714 RunTest_Nesting(MessageLoop::TYPE_IO); | |
| 1715 } | |
| 1716 | |
| 1717 TEST(MessageLoopTest, RecursiveDenial1) { | |
| 1718 RunTest_RecursiveDenial1(MessageLoop::TYPE_DEFAULT); | |
| 1719 RunTest_RecursiveDenial1(MessageLoop::TYPE_UI); | |
| 1720 RunTest_RecursiveDenial1(MessageLoop::TYPE_IO); | |
| 1721 } | |
| 1722 | |
| 1723 TEST(MessageLoopTest, RecursiveDenial3) { | |
| 1724 RunTest_RecursiveDenial3(MessageLoop::TYPE_DEFAULT); | |
| 1725 RunTest_RecursiveDenial3(MessageLoop::TYPE_UI); | |
| 1726 RunTest_RecursiveDenial3(MessageLoop::TYPE_IO); | |
| 1727 } | |
| 1728 | |
| 1729 TEST(MessageLoopTest, RecursiveSupport1) { | |
| 1730 RunTest_RecursiveSupport1(MessageLoop::TYPE_DEFAULT); | |
| 1731 RunTest_RecursiveSupport1(MessageLoop::TYPE_UI); | |
| 1732 RunTest_RecursiveSupport1(MessageLoop::TYPE_IO); | |
| 1733 } | |
| 1734 | |
| 1735 #if defined(OS_WIN) | |
| 1736 // This test occasionally hangs http://crbug.com/44567 | 794 // This test occasionally hangs http://crbug.com/44567 |
| 1737 TEST(MessageLoopTest, DISABLED_RecursiveDenial2) { | 795 TEST(MessageLoopTest, DISABLED_RecursiveDenial2) { |
| 1738 RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT); | 796 RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT); |
| 1739 RunTest_RecursiveDenial2(MessageLoop::TYPE_UI); | 797 RunTest_RecursiveDenial2(MessageLoop::TYPE_UI); |
| 1740 RunTest_RecursiveDenial2(MessageLoop::TYPE_IO); | 798 RunTest_RecursiveDenial2(MessageLoop::TYPE_IO); |
| 1741 } | 799 } |
| 1742 | 800 |
| 1743 TEST(MessageLoopTest, RecursiveSupport2) { | 801 TEST(MessageLoopTest, RecursiveSupport2) { |
| 1744 // This test requires a UI loop | 802 // This test requires a UI loop |
| 1745 RunTest_RecursiveSupport2(MessageLoop::TYPE_UI); | 803 RunTest_RecursiveSupport2(MessageLoop::TYPE_UI); |
| 1746 } | 804 } |
| 1747 #endif // defined(OS_WIN) | 805 #endif // defined(OS_WIN) |
| 1748 | 806 |
| 1749 TEST(MessageLoopTest, NonNestableWithNoNesting) { | |
| 1750 RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_DEFAULT); | |
| 1751 RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_UI); | |
| 1752 RunTest_NonNestableWithNoNesting(MessageLoop::TYPE_IO); | |
| 1753 } | |
| 1754 | |
| 1755 TEST(MessageLoopTest, NonNestableInNestedLoop) { | |
| 1756 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, false); | |
| 1757 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, false); | |
| 1758 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, false); | |
| 1759 } | |
| 1760 | |
| 1761 TEST(MessageLoopTest, NonNestableDelayedInNestedLoop) { | |
| 1762 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_DEFAULT, true); | |
| 1763 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_UI, true); | |
| 1764 RunTest_NonNestableInNestedLoop(MessageLoop::TYPE_IO, true); | |
| 1765 } | |
| 1766 | |
| 1767 TEST(MessageLoopTest, QuitNow) { | |
| 1768 RunTest_QuitNow(MessageLoop::TYPE_DEFAULT); | |
| 1769 RunTest_QuitNow(MessageLoop::TYPE_UI); | |
| 1770 RunTest_QuitNow(MessageLoop::TYPE_IO); | |
| 1771 } | |
| 1772 | |
| 1773 TEST(MessageLoopTest, RunLoopQuitTop) { | |
| 1774 RunTest_RunLoopQuitTop(MessageLoop::TYPE_DEFAULT); | |
| 1775 RunTest_RunLoopQuitTop(MessageLoop::TYPE_UI); | |
| 1776 RunTest_RunLoopQuitTop(MessageLoop::TYPE_IO); | |
| 1777 } | |
| 1778 | |
| 1779 TEST(MessageLoopTest, RunLoopQuitNested) { | |
| 1780 RunTest_RunLoopQuitNested(MessageLoop::TYPE_DEFAULT); | |
| 1781 RunTest_RunLoopQuitNested(MessageLoop::TYPE_UI); | |
| 1782 RunTest_RunLoopQuitNested(MessageLoop::TYPE_IO); | |
| 1783 } | |
| 1784 | |
| 1785 TEST(MessageLoopTest, RunLoopQuitBogus) { | |
| 1786 RunTest_RunLoopQuitBogus(MessageLoop::TYPE_DEFAULT); | |
| 1787 RunTest_RunLoopQuitBogus(MessageLoop::TYPE_UI); | |
| 1788 RunTest_RunLoopQuitBogus(MessageLoop::TYPE_IO); | |
| 1789 } | |
| 1790 | |
| 1791 TEST(MessageLoopTest, RunLoopQuitDeep) { | |
| 1792 RunTest_RunLoopQuitDeep(MessageLoop::TYPE_DEFAULT); | |
| 1793 RunTest_RunLoopQuitDeep(MessageLoop::TYPE_UI); | |
| 1794 RunTest_RunLoopQuitDeep(MessageLoop::TYPE_IO); | |
| 1795 } | |
| 1796 | |
| 1797 TEST(MessageLoopTest, RunLoopQuitOrderBefore) { | |
| 1798 RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_DEFAULT); | |
| 1799 RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_UI); | |
| 1800 RunTest_RunLoopQuitOrderBefore(MessageLoop::TYPE_IO); | |
| 1801 } | |
| 1802 | |
| 1803 TEST(MessageLoopTest, RunLoopQuitOrderDuring) { | |
| 1804 RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_DEFAULT); | |
| 1805 RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_UI); | |
| 1806 RunTest_RunLoopQuitOrderDuring(MessageLoop::TYPE_IO); | |
| 1807 } | |
| 1808 | |
| 1809 TEST(MessageLoopTest, RunLoopQuitOrderAfter) { | |
| 1810 RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_DEFAULT); | |
| 1811 RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_UI); | |
| 1812 RunTest_RunLoopQuitOrderAfter(MessageLoop::TYPE_IO); | |
| 1813 } | |
| 1814 | |
| 1815 class DummyTaskObserver : public MessageLoop::TaskObserver { | 807 class DummyTaskObserver : public MessageLoop::TaskObserver { |
| 1816 public: | 808 public: |
| 1817 explicit DummyTaskObserver(int num_tasks) | 809 explicit DummyTaskObserver(int num_tasks) |
| 1818 : num_tasks_started_(0), | 810 : num_tasks_started_(0), |
| 1819 num_tasks_processed_(0), | 811 num_tasks_processed_(0), |
| 1820 num_tasks_(num_tasks) {} | 812 num_tasks_(num_tasks) {} |
| 1821 | 813 |
| 1822 virtual ~DummyTaskObserver() {} | 814 virtual ~DummyTaskObserver() {} |
| 1823 | 815 |
| 1824 virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE { | 816 virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE { |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2081 EXPECT_EQ(foo->result(), "a"); | 1073 EXPECT_EQ(foo->result(), "a"); |
| 2082 } | 1074 } |
| 2083 | 1075 |
| 2084 TEST(MessageLoopTest, IsType) { | 1076 TEST(MessageLoopTest, IsType) { |
| 2085 MessageLoop loop(MessageLoop::TYPE_UI); | 1077 MessageLoop loop(MessageLoop::TYPE_UI); |
| 2086 EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); | 1078 EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); |
| 2087 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); | 1079 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); |
| 2088 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); | 1080 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); |
| 2089 } | 1081 } |
| 2090 | 1082 |
| 2091 TEST(MessageLoopTest, RecursivePosts) { | |
| 2092 // There was a bug in the MessagePumpGLib where posting tasks recursively | |
| 2093 // caused the message loop to hang, due to the buffer of the internal pipe | |
| 2094 // becoming full. Test all MessageLoop types to ensure this issue does not | |
| 2095 // exist in other MessagePumps. | |
| 2096 | |
| 2097 // On Linux, the pipe buffer size is 64KiB by default. The bug caused one | |
| 2098 // byte accumulated in the pipe per two posts, so we should repeat 128K | |
| 2099 // times to reproduce the bug. | |
| 2100 const int kNumTimes = 1 << 17; | |
| 2101 RunTest_RecursivePosts(MessageLoop::TYPE_DEFAULT, kNumTimes); | |
| 2102 RunTest_RecursivePosts(MessageLoop::TYPE_UI, kNumTimes); | |
| 2103 RunTest_RecursivePosts(MessageLoop::TYPE_IO, kNumTimes); | |
| 2104 } | |
| 2105 | |
| 2106 } // namespace base | 1083 } // namespace base |
| OLD | NEW |