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