1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <vector> 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/compiler_specific.h" 10 #include "base/logging.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop_proxy_impl.h" 14 #include "base/message_loop/message_loop_test.h" 15 #include "base/pending_task.h" 16 #include "base/posix/eintr_wrapper.h" 17 #include "base/run_loop.h" 18 #include "base/synchronization/waitable_event.h" 19 #include "base/thread_task_runner_handle.h" 20 #include "base/threading/platform_thread.h" 21 #include "base/threading/thread.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 #if defined(OS_WIN) 25 #include "base/message_loop/message_pump_dispatcher.h" 26 #include "base/message_loop/message_pump_win.h" 27 #include "base/process/memory.h" 28 #include "base/strings/string16.h" 29 #include "base/win/scoped_handle.h" 30 #endif 31 32 namespace base { 33 34 // TODO(darin): Platform-specific MessageLoop tests should be grouped together 35 // to avoid chopping this file up with so many #ifdefs. 36 37 namespace { 38 39 scoped_ptr<MessagePump> TypeDefaultMessagePumpFactory() { 40 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_DEFAULT); 41 } 42 43 scoped_ptr<MessagePump> TypeIOMessagePumpFactory() { 44 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_IO); 45 } 46 47 scoped_ptr<MessagePump> TypeUIMessagePumpFactory() { 48 return MessageLoop::CreateMessagePumpForType(MessageLoop::TYPE_UI); 49 } 50 51 class Foo : public RefCounted<Foo> { 52 public: 53 Foo() : test_count_(0) { 54 } 55 56 void Test1ConstRef(const std::string& a) { 57 ++test_count_; 58 result_.append(a); 59 } 60 61 int test_count() const { return test_count_; } 62 const std::string& result() const { return result_; } 63 64 private: 65 friend class RefCounted<Foo>; 66 67 ~Foo() {} 68 69 int test_count_; 70 std::string result_; 71 }; 72 73 #if defined(OS_WIN) 74 75 // This function runs slowly to simulate a large amount of work being done. 76 static void SlowFunc(TimeDelta pause, int* quit_counter) { 77 PlatformThread::Sleep(pause); 78 if (--(*quit_counter) == 0) 79 MessageLoop::current()->QuitWhenIdle(); 80 } 81 82 // This function records the time when Run was called in a Time object, which is 83 // useful for building a variety of MessageLoop tests. 84 static void RecordRunTimeFunc(Time* run_time, int* quit_counter) { 85 *run_time = Time::Now(); 86 87 // Cause our Run function to take some time to execute. As a result we can 88 // count on subsequent RecordRunTimeFunc()s running at a future time, 89 // without worry about the resolution of our system clock being an issue. 90 SlowFunc(TimeDelta::FromMilliseconds(10), quit_counter); 91 } 92 93 void SubPumpFunc() { 94 MessageLoop::current()->SetNestableTasksAllowed(true); 95 MSG msg; 96 while (GetMessage(&msg, NULL, 0, 0)) { 97 TranslateMessage(&msg); 98 DispatchMessage(&msg); 99 } 100 MessageLoop::current()->QuitWhenIdle(); 101 } 102 103 void RunTest_PostDelayedTask_SharedTimer_SubPump() { 104 MessageLoop loop(MessageLoop::TYPE_UI); 105 106 // Test that the interval of the timer, used to run the next delayed task, is 107 // set to a value corresponding to when the next delayed task should run. 108 109 // By setting num_tasks to 1, we ensure that the first task to run causes the 110 // run loop to exit. 111 int num_tasks = 1; 112 Time run_time; 113 114 loop.PostTask(FROM_HERE, Bind(&SubPumpFunc)); 115 116 // This very delayed task should never run. 117 loop.PostDelayedTask( 118 FROM_HERE, 119 Bind(&RecordRunTimeFunc, &run_time, &num_tasks), 120 TimeDelta::FromSeconds(1000)); 121 122 // This slightly delayed task should run from within SubPumpFunc). 123 loop.PostDelayedTask( 124 FROM_HERE, 125 Bind(&PostQuitMessage, 0), 126 TimeDelta::FromMilliseconds(10)); 127 128 Time start_time = Time::Now(); 129 130 loop.Run(); 131 EXPECT_EQ(1, num_tasks); 132 133 // Ensure that we ran in far less time than the slower timer. 134 TimeDelta total_time = Time::Now() - start_time; 135 EXPECT_GT(5000, total_time.InMilliseconds()); 136 137 // In case both timers somehow run at nearly the same time, sleep a little 138 // and then run all pending to force them both to have run. This is just 139 // encouraging flakiness if there is any. 140 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); 141 RunLoop().RunUntilIdle(); 142 143 EXPECT_TRUE(run_time.is_null()); 144 } 145 146 const wchar_t kMessageBoxTitle[] = L"MessageLoop Unit Test"; 147 148 enum TaskType { 149 MESSAGEBOX, 150 ENDDIALOG, 151 RECURSIVE, 152 TIMEDMESSAGELOOP, 153 QUITMESSAGELOOP, 154 ORDERED, 155 PUMPS, 156 SLEEP, 157 RUNS, 158 }; 159 160 // Saves the order in which the tasks executed. 161 struct TaskItem { 162 TaskItem(TaskType t, int c, bool s) 163 : type(t), 164 cookie(c), 165 start(s) { 166 } 167 168 TaskType type; 169 int cookie; 170 bool start; 171 172 bool operator == (const TaskItem& other) const { 173 return type == other.type && cookie == other.cookie && start == other.start; 174 } 175 }; 176 177 std::ostream& operator <<(std::ostream& os, TaskType type) { 178 switch (type) { 179 case MESSAGEBOX: os << "MESSAGEBOX"; break; 180 case ENDDIALOG: os << "ENDDIALOG"; break; 181 case RECURSIVE: os << "RECURSIVE"; break; 182 case TIMEDMESSAGELOOP: os << "TIMEDMESSAGELOOP"; break; 183 case QUITMESSAGELOOP: os << "QUITMESSAGELOOP"; break; 184 case ORDERED: os << "ORDERED"; break; 185 case PUMPS: os << "PUMPS"; break; 186 case SLEEP: os << "SLEEP"; break; 187 default: 188 NOTREACHED(); 189 os << "Unknown TaskType"; 190 break; 191 } 192 return os; 193 } 194 195 std::ostream& operator <<(std::ostream& os, const TaskItem& item) { 196 if (item.start) 197 return os << item.type << " " << item.cookie << " starts"; 198 else 199 return os << item.type << " " << item.cookie << " ends"; 200 } 201 202 class TaskList { 203 public: 204 void RecordStart(TaskType type, int cookie) { 205 TaskItem item(type, cookie, true); 206 DVLOG(1) << item; 207 task_list_.push_back(item); 208 } 209 210 void RecordEnd(TaskType type, int cookie) { 211 TaskItem item(type, cookie, false); 212 DVLOG(1) << item; 213 task_list_.push_back(item); 214 } 215 216 size_t Size() { 217 return task_list_.size(); 218 } 219 220 TaskItem Get(int n) { 221 return task_list_[n]; 222 } 223 224 private: 225 std::vector<TaskItem> task_list_; 226 }; 227 228 // MessageLoop implicitly start a "modal message loop". Modal dialog boxes, 229 // common controls (like OpenFile) and StartDoc printing function can cause 230 // implicit message loops. 231 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) { 232 order->RecordStart(MESSAGEBOX, cookie); 233 if (is_reentrant) 234 MessageLoop::current()->SetNestableTasksAllowed(true); 235 MessageBox(NULL, L"Please wait...", kMessageBoxTitle, MB_OK); 236 order->RecordEnd(MESSAGEBOX, cookie); 237 } 238 239 // Will end the MessageBox. 240 void EndDialogFunc(TaskList* order, int cookie) { 241 order->RecordStart(ENDDIALOG, cookie); 242 HWND window = GetActiveWindow(); 243 if (window != NULL) { 244 EXPECT_NE(EndDialog(window, IDCONTINUE), 0); 245 // Cheap way to signal that the window wasn't found if RunEnd() isn't 246 // called. 247 order->RecordEnd(ENDDIALOG, cookie); 248 } 249 } 250 251 void RecursiveFunc(TaskList* order, int cookie, int depth, 252 bool is_reentrant) { 253 order->RecordStart(RECURSIVE, cookie); 254 if (depth > 0) { 255 if (is_reentrant) 256 MessageLoop::current()->SetNestableTasksAllowed(true); 257 MessageLoop::current()->PostTask( 258 FROM_HERE, 259 Bind(&RecursiveFunc, order, cookie, depth - 1, is_reentrant)); 260 } 261 order->RecordEnd(RECURSIVE, cookie); 262 } 263 264 void QuitFunc(TaskList* order, int cookie) { 265 order->RecordStart(QUITMESSAGELOOP, cookie); 266 MessageLoop::current()->QuitWhenIdle(); 267 order->RecordEnd(QUITMESSAGELOOP, cookie); 268 } 269 270 void RecursiveFuncWin(MessageLoop* target, 271 HANDLE event, 272 bool expect_window, 273 TaskList* order, 274 bool is_reentrant) { 275 target->PostTask(FROM_HERE, 276 Bind(&RecursiveFunc, order, 1, 2, is_reentrant)); 277 target->PostTask(FROM_HERE, 278 Bind(&MessageBoxFunc, order, 2, is_reentrant)); 279 target->PostTask(FROM_HERE, 280 Bind(&RecursiveFunc, order, 3, 2, is_reentrant)); 281 // The trick here is that for recursive task processing, this task will be 282 // ran _inside_ the MessageBox message loop, dismissing the MessageBox 283 // without a chance. 284 // For non-recursive task processing, this will be executed _after_ the 285 // MessageBox will have been dismissed by the code below, where 286 // expect_window_ is true. 287 target->PostTask(FROM_HERE, 288 Bind(&EndDialogFunc, order, 4)); 289 target->PostTask(FROM_HERE, 290 Bind(&QuitFunc, order, 5)); 291 292 // Enforce that every tasks are sent before starting to run the main thread 293 // message loop. 294 ASSERT_TRUE(SetEvent(event)); 295 296 // Poll for the MessageBox. Don't do this at home! At the speed we do it, 297 // you will never realize one MessageBox was shown. 298 for (; expect_window;) { 299 HWND window = FindWindow(L"#32770", kMessageBoxTitle); 300 if (window) { 301 // Dismiss it. 302 for (;;) { 303 HWND button = FindWindowEx(window, NULL, L"Button", NULL); 304 if (button != NULL) { 305 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONDOWN, 0, 0)); 306 EXPECT_EQ(0, SendMessage(button, WM_LBUTTONUP, 0, 0)); 307 break; 308 } 309 } 310 break; 311 } 312 } 313 } 314 315 // TODO(darin): These tests need to be ported since they test critical 316 // message loop functionality. 317 318 // A side effect of this test is the generation a beep. Sorry. 319 void RunTest_RecursiveDenial2(MessageLoop::Type message_loop_type) { 320 MessageLoop loop(message_loop_type); 321 322 Thread worker("RecursiveDenial2_worker"); 323 Thread::Options options; 324 options.message_loop_type = message_loop_type; 325 ASSERT_EQ(true, worker.StartWithOptions(options)); 326 TaskList order; 327 win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); 328 worker.message_loop()->PostTask(FROM_HERE, 329 Bind(&RecursiveFuncWin, 330 MessageLoop::current(), 331 event.Get(), 332 true, 333 &order, 334 false)); 335 // Let the other thread execute. 336 WaitForSingleObject(event, INFINITE); 337 MessageLoop::current()->Run(); 338 339 ASSERT_EQ(order.Size(), 17); 340 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); 341 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); 342 EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true)); 343 EXPECT_EQ(order.Get(3), TaskItem(MESSAGEBOX, 2, false)); 344 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, true)); 345 EXPECT_EQ(order.Get(5), TaskItem(RECURSIVE, 3, false)); 346 // When EndDialogFunc is processed, the window is already dismissed, hence no 347 // "end" entry. 348 EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, true)); 349 EXPECT_EQ(order.Get(7), TaskItem(QUITMESSAGELOOP, 5, true)); 350 EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, false)); 351 EXPECT_EQ(order.Get(9), TaskItem(RECURSIVE, 1, true)); 352 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, false)); 353 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 3, true)); 354 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, false)); 355 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 1, true)); 356 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, false)); 357 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 3, true)); 358 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, false)); 359 } 360 361 // A side effect of this test is the generation a beep. Sorry. This test also 362 // needs to process windows messages on the current thread. 363 void RunTest_RecursiveSupport2(MessageLoop::Type message_loop_type) { 364 MessageLoop loop(message_loop_type); 365 366 Thread worker("RecursiveSupport2_worker"); 367 Thread::Options options; 368 options.message_loop_type = message_loop_type; 369 ASSERT_EQ(true, worker.StartWithOptions(options)); 370 TaskList order; 371 win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, NULL)); 372 worker.message_loop()->PostTask(FROM_HERE, 373 Bind(&RecursiveFuncWin, 374 MessageLoop::current(), 375 event.Get(), 376 false, 377 &order, 378 true)); 379 // Let the other thread execute. 380 WaitForSingleObject(event, INFINITE); 381 MessageLoop::current()->Run(); 382 383 ASSERT_EQ(order.Size(), 18); 384 EXPECT_EQ(order.Get(0), TaskItem(RECURSIVE, 1, true)); 385 EXPECT_EQ(order.Get(1), TaskItem(RECURSIVE, 1, false)); 386 EXPECT_EQ(order.Get(2), TaskItem(MESSAGEBOX, 2, true)); 387 // Note that this executes in the MessageBox modal loop. 388 EXPECT_EQ(order.Get(3), TaskItem(RECURSIVE, 3, true)); 389 EXPECT_EQ(order.Get(4), TaskItem(RECURSIVE, 3, false)); 390 EXPECT_EQ(order.Get(5), TaskItem(ENDDIALOG, 4, true)); 391 EXPECT_EQ(order.Get(6), TaskItem(ENDDIALOG, 4, false)); 392 EXPECT_EQ(order.Get(7), TaskItem(MESSAGEBOX, 2, false)); 393 /* The order can subtly change here. The reason is that when RecursiveFunc(1) 394 is called in the main thread, if it is faster than getting to the 395 PostTask(FROM_HERE, Bind(&QuitFunc) execution, the order of task 396 execution can change. We don't care anyway that the order isn't correct. 397 EXPECT_EQ(order.Get(8), TaskItem(QUITMESSAGELOOP, 5, true)); 398 EXPECT_EQ(order.Get(9), TaskItem(QUITMESSAGELOOP, 5, false)); 399 EXPECT_EQ(order.Get(10), TaskItem(RECURSIVE, 1, true)); 400 EXPECT_EQ(order.Get(11), TaskItem(RECURSIVE, 1, false)); 401 */ 402 EXPECT_EQ(order.Get(12), TaskItem(RECURSIVE, 3, true)); 403 EXPECT_EQ(order.Get(13), TaskItem(RECURSIVE, 3, false)); 404 EXPECT_EQ(order.Get(14), TaskItem(RECURSIVE, 1, true)); 405 EXPECT_EQ(order.Get(15), TaskItem(RECURSIVE, 1, false)); 406 EXPECT_EQ(order.Get(16), TaskItem(RECURSIVE, 3, true)); 407 EXPECT_EQ(order.Get(17), TaskItem(RECURSIVE, 3, false)); 408 } 409 410 #endif // defined(OS_WIN) 411 412 void PostNTasksThenQuit(int posts_remaining) { 413 if (posts_remaining > 1) { 414 MessageLoop::current()->PostTask( 415 FROM_HERE, 416 Bind(&PostNTasksThenQuit, posts_remaining - 1)); 417 } else { 418 MessageLoop::current()->QuitWhenIdle(); 419 } 420 } 421 422 #if defined(OS_WIN) 423 424 class DispatcherImpl : public MessagePumpDispatcher { 425 public: 426 DispatcherImpl() : dispatch_count_(0) {} 427 428 virtual uint32_t Dispatch(const NativeEvent& msg) OVERRIDE { 429 ::TranslateMessage(&msg); 430 ::DispatchMessage(&msg); 431 // Do not count WM_TIMER since it is not what we post and it will cause 432 // flakiness. 433 if (msg.message != WM_TIMER) 434 ++dispatch_count_; 435 // We treat WM_LBUTTONUP as the last message. 436 return msg.message == WM_LBUTTONUP ? POST_DISPATCH_QUIT_LOOP 437 : POST_DISPATCH_NONE; 438 } 439 440 int dispatch_count_; 441 }; 442 443 void MouseDownUp() { 444 PostMessage(NULL, WM_LBUTTONDOWN, 0, 0); 445 PostMessage(NULL, WM_LBUTTONUP, 'A', 0); 446 } 447 448 void RunTest_Dispatcher(MessageLoop::Type message_loop_type) { 449 MessageLoop loop(message_loop_type); 450 451 MessageLoop::current()->PostDelayedTask( 452 FROM_HERE, 453 Bind(&MouseDownUp), 454 TimeDelta::FromMilliseconds(100)); 455 DispatcherImpl dispatcher; 456 RunLoop run_loop(&dispatcher); 457 run_loop.Run(); 458 ASSERT_EQ(2, dispatcher.dispatch_count_); 459 } 460 461 LRESULT CALLBACK MsgFilterProc(int code, WPARAM wparam, LPARAM lparam) { 462 if (code == MessagePumpForUI::kMessageFilterCode) { 463 MSG* msg = reinterpret_cast<MSG*>(lparam); 464 if (msg->message == WM_LBUTTONDOWN) 465 return TRUE; 466 } 467 return FALSE; 468 } 469 470 void RunTest_DispatcherWithMessageHook(MessageLoop::Type message_loop_type) { 471 MessageLoop loop(message_loop_type); 472 473 MessageLoop::current()->PostDelayedTask( 474 FROM_HERE, 475 Bind(&MouseDownUp), 476 TimeDelta::FromMilliseconds(100)); 477 HHOOK msg_hook = SetWindowsHookEx(WH_MSGFILTER, 478 MsgFilterProc, 479 NULL, 480 GetCurrentThreadId()); 481 DispatcherImpl dispatcher; 482 RunLoop run_loop(&dispatcher); 483 run_loop.Run(); 484 ASSERT_EQ(1, dispatcher.dispatch_count_); 485 UnhookWindowsHookEx(msg_hook); 486 } 487 488 class TestIOHandler : public MessageLoopForIO::IOHandler { 489 public: 490 TestIOHandler(const wchar_t* name, HANDLE signal, bool wait); 491 492 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, 493 DWORD bytes_transfered, DWORD error); 494 495 void Init(); 496 void WaitForIO(); 497 OVERLAPPED* context() { return &context_.overlapped; } 498 DWORD size() { return sizeof(buffer_); } 499 500 private: 501 char buffer_[48]; 502 MessageLoopForIO::IOContext context_; 503 HANDLE signal_; 504 win::ScopedHandle file_; 505 bool wait_; 506 }; 507 508 TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait) 509 : signal_(signal), wait_(wait) { 510 memset(buffer_, 0, sizeof(buffer_)); 511 memset(&context_, 0, sizeof(context_)); 512 context_.handler = this; 513 514 file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 515 FILE_FLAG_OVERLAPPED, NULL)); 516 EXPECT_TRUE(file_.IsValid()); 517 } 518 519 void TestIOHandler::Init() { 520 MessageLoopForIO::current()->RegisterIOHandler(file_, this); 521 522 DWORD read; 523 EXPECT_FALSE(ReadFile(file_, buffer_, size(), &read, context())); 524 EXPECT_EQ(ERROR_IO_PENDING, GetLastError()); 525 if (wait_) 526 WaitForIO(); 527 } 528 529 void TestIOHandler::OnIOCompleted(MessageLoopForIO::IOContext* context, 530 DWORD bytes_transfered, DWORD error) { 531 ASSERT_TRUE(context == &context_); 532 ASSERT_TRUE(SetEvent(signal_)); 533 } 534 535 void TestIOHandler::WaitForIO() { 536 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(300, this)); 537 EXPECT_TRUE(MessageLoopForIO::current()->WaitForIOCompletion(400, this)); 538 } 539 540 void RunTest_IOHandler() { 541 win::ScopedHandle callback_called(CreateEvent(NULL, TRUE, FALSE, NULL)); 542 ASSERT_TRUE(callback_called.IsValid()); 543 544 const wchar_t* kPipeName = L"\\\\.\\pipe\\iohandler_pipe"; 545 win::ScopedHandle server( 546 CreateNamedPipe(kPipeName, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); 547 ASSERT_TRUE(server.IsValid()); 548 549 Thread thread("IOHandler test"); 550 Thread::Options options; 551 options.message_loop_type = MessageLoop::TYPE_IO; 552 ASSERT_TRUE(thread.StartWithOptions(options)); 553 554 MessageLoop* thread_loop = thread.message_loop(); 555 ASSERT_TRUE(NULL != thread_loop); 556 557 TestIOHandler handler(kPipeName, callback_called, false); 558 thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init, 559 Unretained(&handler))); 560 // Make sure the thread runs and sleeps for lack of work. 561 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); 562 563 const char buffer[] = "Hello there!"; 564 DWORD written; 565 EXPECT_TRUE(WriteFile(server, buffer, sizeof(buffer), &written, NULL)); 566 567 DWORD result = WaitForSingleObject(callback_called, 1000); 568 EXPECT_EQ(WAIT_OBJECT_0, result); 569 570 thread.Stop(); 571 } 572 573 void RunTest_WaitForIO() { 574 win::ScopedHandle callback1_called( 575 CreateEvent(NULL, TRUE, FALSE, NULL)); 576 win::ScopedHandle callback2_called( 577 CreateEvent(NULL, TRUE, FALSE, NULL)); 578 ASSERT_TRUE(callback1_called.IsValid()); 579 ASSERT_TRUE(callback2_called.IsValid()); 580 581 const wchar_t* kPipeName1 = L"\\\\.\\pipe\\iohandler_pipe1"; 582 const wchar_t* kPipeName2 = L"\\\\.\\pipe\\iohandler_pipe2"; 583 win::ScopedHandle server1( 584 CreateNamedPipe(kPipeName1, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); 585 win::ScopedHandle server2( 586 CreateNamedPipe(kPipeName2, PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0, 0, NULL)); 587 ASSERT_TRUE(server1.IsValid()); 588 ASSERT_TRUE(server2.IsValid()); 589 590 Thread thread("IOHandler test"); 591 Thread::Options options; 592 options.message_loop_type = MessageLoop::TYPE_IO; 593 ASSERT_TRUE(thread.StartWithOptions(options)); 594 595 MessageLoop* thread_loop = thread.message_loop(); 596 ASSERT_TRUE(NULL != thread_loop); 597 598 TestIOHandler handler1(kPipeName1, callback1_called, false); 599 TestIOHandler handler2(kPipeName2, callback2_called, true); 600 thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init, 601 Unretained(&handler1))); 602 // TODO(ajwong): Do we really need such long Sleeps in ths function? 603 // Make sure the thread runs and sleeps for lack of work. 604 TimeDelta delay = TimeDelta::FromMilliseconds(100); 605 PlatformThread::Sleep(delay); 606 thread_loop->PostTask(FROM_HERE, Bind(&TestIOHandler::Init, 607 Unretained(&handler2))); 608 PlatformThread::Sleep(delay); 609 610 // At this time handler1 is waiting to be called, and the thread is waiting 611 // on the Init method of handler2, filtering only handler2 callbacks. 612 613 const char buffer[] = "Hello there!"; 614 DWORD written; 615 EXPECT_TRUE(WriteFile(server1, buffer, sizeof(buffer), &written, NULL)); 616 PlatformThread::Sleep(2 * delay); 617 EXPECT_EQ(WAIT_TIMEOUT, WaitForSingleObject(callback1_called, 0)) << 618 "handler1 has not been called"; 619 620 EXPECT_TRUE(WriteFile(server2, buffer, sizeof(buffer), &written, NULL)); 621 622 HANDLE objects[2] = { callback1_called.Get(), callback2_called.Get() }; 623 DWORD result = WaitForMultipleObjects(2, objects, TRUE, 1000); 624 EXPECT_EQ(WAIT_OBJECT_0, result); 625 626 thread.Stop(); 627 } 628 629 #endif // defined(OS_WIN) 630 631 } // namespace 632 633 //----------------------------------------------------------------------------- 634 // Each test is run against each type of MessageLoop. That way we are sure 635 // that message loops work properly in all configurations. Of course, in some 636 // cases, a unit test may only be for a particular type of loop. 637 638 RUN_MESSAGE_LOOP_TESTS(Default, &TypeDefaultMessagePumpFactory); 639 RUN_MESSAGE_LOOP_TESTS(UI, &TypeUIMessagePumpFactory); 640 RUN_MESSAGE_LOOP_TESTS(IO, &TypeIOMessagePumpFactory); 641 642 #if defined(OS_WIN) 643 TEST(MessageLoopTest, PostDelayedTask_SharedTimer_SubPump) { 644 RunTest_PostDelayedTask_SharedTimer_SubPump(); 645 } 646 647 // This test occasionally hangs http://crbug.com/44567 648 TEST(MessageLoopTest, DISABLED_RecursiveDenial2) { 649 RunTest_RecursiveDenial2(MessageLoop::TYPE_DEFAULT); 650 RunTest_RecursiveDenial2(MessageLoop::TYPE_UI); 651 RunTest_RecursiveDenial2(MessageLoop::TYPE_IO); 652 } 653 654 TEST(MessageLoopTest, RecursiveSupport2) { 655 // This test requires a UI loop 656 RunTest_RecursiveSupport2(MessageLoop::TYPE_UI); 657 } 658 #endif // defined(OS_WIN) 659 660 class DummyTaskObserver : public MessageLoop::TaskObserver { 661 public: 662 explicit DummyTaskObserver(int num_tasks) 663 : num_tasks_started_(0), 664 num_tasks_processed_(0), 665 num_tasks_(num_tasks) {} 666 667 virtual ~DummyTaskObserver() {} 668 669 virtual void WillProcessTask(const PendingTask& pending_task) OVERRIDE { 670 num_tasks_started_++; 671 EXPECT_TRUE(pending_task.time_posted != TimeTicks()); 672 EXPECT_LE(num_tasks_started_, num_tasks_); 673 EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1); 674 } 675 676 virtual void DidProcessTask(const PendingTask& pending_task) OVERRIDE { 677 num_tasks_processed_++; 678 EXPECT_TRUE(pending_task.time_posted != TimeTicks()); 679 EXPECT_LE(num_tasks_started_, num_tasks_); 680 EXPECT_EQ(num_tasks_started_, num_tasks_processed_); 681 } 682 683 int num_tasks_started() const { return num_tasks_started_; } 684 int num_tasks_processed() const { return num_tasks_processed_; } 685 686 private: 687 int num_tasks_started_; 688 int num_tasks_processed_; 689 const int num_tasks_; 690 691 DISALLOW_COPY_AND_ASSIGN(DummyTaskObserver); 692 }; 693 694 TEST(MessageLoopTest, TaskObserver) { 695 const int kNumPosts = 6; 696 DummyTaskObserver observer(kNumPosts); 697 698 MessageLoop loop; 699 loop.AddTaskObserver(&observer); 700 loop.PostTask(FROM_HERE, Bind(&PostNTasksThenQuit, kNumPosts)); 701 loop.Run(); 702 loop.RemoveTaskObserver(&observer); 703 704 EXPECT_EQ(kNumPosts, observer.num_tasks_started()); 705 EXPECT_EQ(kNumPosts, observer.num_tasks_processed()); 706 } 707 708 #if defined(OS_WIN) 709 TEST(MessageLoopTest, Dispatcher) { 710 // This test requires a UI loop 711 RunTest_Dispatcher(MessageLoop::TYPE_UI); 712 } 713 714 TEST(MessageLoopTest, DispatcherWithMessageHook) { 715 // This test requires a UI loop 716 RunTest_DispatcherWithMessageHook(MessageLoop::TYPE_UI); 717 } 718 719 TEST(MessageLoopTest, IOHandler) { 720 RunTest_IOHandler(); 721 } 722 723 TEST(MessageLoopTest, WaitForIO) { 724 RunTest_WaitForIO(); 725 } 726 727 TEST(MessageLoopTest, HighResolutionTimer) { 728 MessageLoop loop; 729 730 const TimeDelta kFastTimer = TimeDelta::FromMilliseconds(5); 731 const TimeDelta kSlowTimer = TimeDelta::FromMilliseconds(100); 732 733 EXPECT_FALSE(loop.IsHighResolutionTimerEnabledForTesting()); 734 735 // Post a fast task to enable the high resolution timers. 736 loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1), 737 kFastTimer); 738 loop.Run(); 739 EXPECT_TRUE(loop.IsHighResolutionTimerEnabledForTesting()); 740 741 // Post a slow task and verify high resolution timers 742 // are still enabled. 743 loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1), 744 kSlowTimer); 745 loop.Run(); 746 EXPECT_TRUE(loop.IsHighResolutionTimerEnabledForTesting()); 747 748 // Wait for a while so that high-resolution mode elapses. 749 PlatformThread::Sleep(TimeDelta::FromMilliseconds( 750 MessageLoop::kHighResolutionTimerModeLeaseTimeMs)); 751 752 // Post a slow task to disable the high resolution timers. 753 loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1), 754 kSlowTimer); 755 loop.Run(); 756 EXPECT_FALSE(loop.IsHighResolutionTimerEnabledForTesting()); 757 } 758 759 #endif // defined(OS_WIN) 760 761 #if defined(OS_POSIX) && !defined(OS_NACL) 762 763 namespace { 764 765 class QuitDelegate : public MessageLoopForIO::Watcher { 766 public: 767 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE { 768 MessageLoop::current()->QuitWhenIdle(); 769 } 770 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE { 771 MessageLoop::current()->QuitWhenIdle(); 772 } 773 }; 774 775 TEST(MessageLoopTest, FileDescriptorWatcherOutlivesMessageLoop) { 776 // Simulate a MessageLoop that dies before an FileDescriptorWatcher. 777 // This could happen when people use the Singleton pattern or atexit. 778 779 // Create a file descriptor. Doesn't need to be readable or writable, 780 // as we don't need to actually get any notifications. 781 // pipe() is just the easiest way to do it. 782 int pipefds[2]; 783 int err = pipe(pipefds); 784 ASSERT_EQ(0, err); 785 int fd = pipefds[1]; 786 { 787 // Arrange for controller to live longer than message loop. 788 MessageLoopForIO::FileDescriptorWatcher controller; 789 { 790 MessageLoopForIO message_loop; 791 792 QuitDelegate delegate; 793 message_loop.WatchFileDescriptor(fd, 794 true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate); 795 // and don't run the message loop, just destroy it. 796 } 797 } 798 if (IGNORE_EINTR(close(pipefds[0])) < 0) 799 PLOG(ERROR) << "close"; 800 if (IGNORE_EINTR(close(pipefds[1])) < 0) 801 PLOG(ERROR) << "close"; 802 } 803 804 TEST(MessageLoopTest, FileDescriptorWatcherDoubleStop) { 805 // Verify that it's ok to call StopWatchingFileDescriptor(). 806 // (Errors only showed up in valgrind.) 807 int pipefds[2]; 808 int err = pipe(pipefds); 809 ASSERT_EQ(0, err); 810 int fd = pipefds[1]; 811 { 812 // Arrange for message loop to live longer than controller. 813 MessageLoopForIO message_loop; 814 { 815 MessageLoopForIO::FileDescriptorWatcher controller; 816 817 QuitDelegate delegate; 818 message_loop.WatchFileDescriptor(fd, 819 true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate); 820 controller.StopWatchingFileDescriptor(); 821 } 822 } 823 if (IGNORE_EINTR(close(pipefds[0])) < 0) 824 PLOG(ERROR) << "close"; 825 if (IGNORE_EINTR(close(pipefds[1])) < 0) 826 PLOG(ERROR) << "close"; 827 } 828 829 } // namespace 830 831 #endif // defined(OS_POSIX) && !defined(OS_NACL) 832 833 namespace { 834 // Inject a test point for recording the destructor calls for Closure objects 835 // send to MessageLoop::PostTask(). It is awkward usage since we are trying to 836 // hook the actual destruction, which is not a common operation. 837 class DestructionObserverProbe : 838 public RefCounted<DestructionObserverProbe> { 839 public: 840 DestructionObserverProbe(bool* task_destroyed, 841 bool* destruction_observer_called) 842 : task_destroyed_(task_destroyed), 843 destruction_observer_called_(destruction_observer_called) { 844 } 845 virtual void Run() { 846 // This task should never run. 847 ADD_FAILURE(); 848 } 849 private: 850 friend class RefCounted<DestructionObserverProbe>; 851 852 virtual ~DestructionObserverProbe() { 853 EXPECT_FALSE(*destruction_observer_called_); 854 *task_destroyed_ = true; 855 } 856 857 bool* task_destroyed_; 858 bool* destruction_observer_called_; 859 }; 860 861 class MLDestructionObserver : public MessageLoop::DestructionObserver { 862 public: 863 MLDestructionObserver(bool* task_destroyed, bool* destruction_observer_called) 864 : task_destroyed_(task_destroyed), 865 destruction_observer_called_(destruction_observer_called), 866 task_destroyed_before_message_loop_(false) { 867 } 868 virtual void WillDestroyCurrentMessageLoop() OVERRIDE { 869 task_destroyed_before_message_loop_ = *task_destroyed_; 870 *destruction_observer_called_ = true; 871 } 872 bool task_destroyed_before_message_loop() const { 873 return task_destroyed_before_message_loop_; 874 } 875 private: 876 bool* task_destroyed_; 877 bool* destruction_observer_called_; 878 bool task_destroyed_before_message_loop_; 879 }; 880 881 } // namespace 882 883 TEST(MessageLoopTest, DestructionObserverTest) { 884 // Verify that the destruction observer gets called at the very end (after 885 // all the pending tasks have been destroyed). 886 MessageLoop* loop = new MessageLoop; 887 const TimeDelta kDelay = TimeDelta::FromMilliseconds(100); 888 889 bool task_destroyed = false; 890 bool destruction_observer_called = false; 891 892 MLDestructionObserver observer(&task_destroyed, &destruction_observer_called); 893 loop->AddDestructionObserver(&observer); 894 loop->PostDelayedTask( 895 FROM_HERE, 896 Bind(&DestructionObserverProbe::Run, 897 new DestructionObserverProbe(&task_destroyed, 898 &destruction_observer_called)), 899 kDelay); 900 delete loop; 901 EXPECT_TRUE(observer.task_destroyed_before_message_loop()); 902 // The task should have been destroyed when we deleted the loop. 903 EXPECT_TRUE(task_destroyed); 904 EXPECT_TRUE(destruction_observer_called); 905 } 906 907 908 // Verify that MessageLoop sets ThreadMainTaskRunner::current() and it 909 // posts tasks on that message loop. 910 TEST(MessageLoopTest, ThreadMainTaskRunner) { 911 MessageLoop loop; 912 913 scoped_refptr<Foo> foo(new Foo()); 914 std::string a("a"); 915 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, Bind( 916 &Foo::Test1ConstRef, foo.get(), a)); 917 918 // Post quit task; 919 MessageLoop::current()->PostTask(FROM_HERE, Bind( 920 &MessageLoop::Quit, Unretained(MessageLoop::current()))); 921 922 // Now kick things off 923 MessageLoop::current()->Run(); 924 925 EXPECT_EQ(foo->test_count(), 1); 926 EXPECT_EQ(foo->result(), "a"); 927 } 928 929 TEST(MessageLoopTest, IsType) { 930 MessageLoop loop(MessageLoop::TYPE_UI); 931 EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); 932 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); 933 EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); 934 } 935 936 #if defined(OS_WIN) 937 void EmptyFunction() {} 938 939 void PostMultipleTasks() { 940 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&EmptyFunction)); 941 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&EmptyFunction)); 942 } 943 944 static const int kSignalMsg = WM_USER + 2; 945 946 void PostWindowsMessage(HWND message_hwnd) { 947 PostMessage(message_hwnd, kSignalMsg, 0, 2); 948 } 949 950 void EndTest(bool* did_run, HWND hwnd) { 951 *did_run = true; 952 PostMessage(hwnd, WM_CLOSE, 0, 0); 953 } 954 955 int kMyMessageFilterCode = 0x5002; 956 957 LRESULT CALLBACK TestWndProcThunk(HWND hwnd, UINT message, 958 WPARAM wparam, LPARAM lparam) { 959 if (message == WM_CLOSE) 960 EXPECT_TRUE(DestroyWindow(hwnd)); 961 if (message != kSignalMsg) 962 return DefWindowProc(hwnd, message, wparam, lparam); 963 964 switch (lparam) { 965 case 1: 966 // First, we post a task that will post multiple no-op tasks to make sure 967 // that the pump's incoming task queue does not become empty during the 968 // test. 969 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&PostMultipleTasks)); 970 // Next, we post a task that posts a windows message to trigger the second 971 // stage of the test. 972 MessageLoop::current()->PostTask(FROM_HERE, 973 base::Bind(&PostWindowsMessage, hwnd)); 974 break; 975 case 2: 976 // Since we're about to enter a modal loop, tell the message loop that we 977 // intend to nest tasks. 978 MessageLoop::current()->SetNestableTasksAllowed(true); 979 bool did_run = false; 980 MessageLoop::current()->PostTask(FROM_HERE, 981 base::Bind(&EndTest, &did_run, hwnd)); 982 // Run a nested windows-style message loop and verify that our task runs. If 983 // it doesn't, then we'll loop here until the test times out. 984 MSG msg; 985 while (GetMessage(&msg, 0, 0, 0)) { 986 if (!CallMsgFilter(&msg, kMyMessageFilterCode)) 987 DispatchMessage(&msg); 988 // If this message is a WM_CLOSE, explicitly exit the modal loop. Posting 989 // a WM_QUIT should handle this, but unfortunately MessagePumpWin eats 990 // WM_QUIT messages even when running inside a modal loop. 991 if (msg.message == WM_CLOSE) 992 break; 993 } 994 EXPECT_TRUE(did_run); 995 MessageLoop::current()->Quit(); 996 break; 997 } 998 return 0; 999 } 1000 1001 TEST(MessageLoopTest, AlwaysHaveUserMessageWhenNesting) { 1002 MessageLoop loop(MessageLoop::TYPE_UI); 1003 HINSTANCE instance = GetModuleFromAddress(&TestWndProcThunk); 1004 WNDCLASSEX wc = {0}; 1005 wc.cbSize = sizeof(wc); 1006 wc.lpfnWndProc = TestWndProcThunk; 1007 wc.hInstance = instance; 1008 wc.lpszClassName = L"MessageLoopTest_HWND"; 1009 ATOM atom = RegisterClassEx(&wc); 1010 ASSERT_TRUE(atom); 1011 1012 HWND message_hwnd = CreateWindow(MAKEINTATOM(atom), 0, 0, 0, 0, 0, 0, 1013 HWND_MESSAGE, 0, instance, 0); 1014 ASSERT_TRUE(message_hwnd) << GetLastError(); 1015 1016 ASSERT_TRUE(PostMessage(message_hwnd, kSignalMsg, 0, 1)); 1017 1018 loop.Run(); 1019 1020 ASSERT_TRUE(UnregisterClass(MAKEINTATOM(atom), instance)); 1021 } 1022 #endif // defined(OS_WIN) 1023 1024 } // namespace base 1025