1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
780a33eee125c56b3ee00067d47aad2a7dbab3023Kristian Monsen#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(ANDROID)
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <gdk/gdk.h>
9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <gdk/gdkx.h>
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <algorithm>
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/compiler_specific.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/lazy_instance.h"
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump_default.h"
18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h"
193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_local.h"
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_MACOSX)
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump_mac.h"
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_POSIX)
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump_libevent.h"
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_POSIX) && !defined(OS_MACOSX)
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump_glib.h"
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
31513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(TOUCH_UI)
32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/message_pump_glib_x.h"
33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::TimeDelta;
36513209b27ff55e2841eac0e4120199c23acce758Ben Murdochusing base::TimeTicks;
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A lazily created thread local storage for quick access to a thread's message
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// loop, if one exists.  This should be safe and free of static constructors.
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbase::LazyInstance<base::ThreadLocalPointer<MessageLoop> > lazy_tls_ptr(
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    base::LINKER_INITIALIZED);
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Logical events for Histogram profiling. Run with -message-loop-histogrammer
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to get an accounting of messages and actions taken on each thread.
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTaskRunEvent = 0x1;
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTimerEvent = 0x2;
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Provide range of message IDs for use in histogramming and debug display.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kLeastNonZeroMessageId = 1;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kMaxMessageId = 1099;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kNumberOfDistinctMessagesDisplayed = 1100;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Provide a macro that takes an expression (such as a constant, or macro
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// constant) and creates a pair to initalize an array of pairs.  In this case,
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// our pair consists of the expressions value, and the "stringized" version
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of the expression (i.e., the exrpression put in quotes).  For example, if
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// we have:
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//    #define FOO 2
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//    #define BAR 5
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// then the following:
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//    VALUE_TO_NUMBER_AND_NAME(FOO + BAR)
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will expand to:
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   {7, "FOO + BAR"}
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We use the resulting array as an argument to our histogram, which reads the
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// number as a bucket identifier, and proceeds to use the corresponding name
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in the pair (i.e., the quoted string) when printing out a histogram.
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define VALUE_TO_NUMBER_AND_NAME(name) {name, #name},
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst base::LinearHistogram::DescriptionPair event_descriptions_[] = {
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Provide some pretty print capability in our histogram for our internal
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // messages.
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A few events we handle (kindred to messages), and used to profile actions.
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent)
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VALUE_TO_NUMBER_AND_NAME(kTimerEvent)
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {-1, NULL}  // The list must be null terminated, per API to histogram.
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool enable_histogrammer_ = false;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Upon a SEH exception in this thread, it restores the original unhandled
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// exception filter.
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) {
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ::SetUnhandledExceptionFilter(old_filter);
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return EXCEPTION_CONTINUE_SEARCH;
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Retrieves a pointer to the current unhandled exception filter. There
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// is no standalone getter method.
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic LPTOP_LEVEL_EXCEPTION_FILTER GetTopSEHFilter() {
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  LPTOP_LEVEL_EXCEPTION_FILTER top_filter = NULL;
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  top_filter = ::SetUnhandledExceptionFilter(0);
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ::SetUnhandledExceptionFilter(top_filter);
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return top_filter;
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // defined(OS_WIN)
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMessageLoop::TaskObserver::TaskObserver() {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMessageLoop::TaskObserver::~TaskObserver() {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMessageLoop::DestructionObserver::~DestructionObserver() {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//------------------------------------------------------------------------------
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMessageLoop::MessageLoop(Type type)
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : type_(type),
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      nestable_tasks_allowed_(true),
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      exception_restoration_(false),
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      message_histogram_(NULL),
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      state_(NULL),
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef OS_WIN
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      os_modal_loop_(false),
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif  // OS_WIN
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      next_sequence_num_(0) {
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!current()) << "should only have one message loop per thread";
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  lazy_tls_ptr.Pointer()->Set(this);
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(rvargas): Get rid of the OS guards.
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_UI new base::MessagePumpForUI()
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpForIO()
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_UI base::MessagePumpMac::Create()
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
14100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#elif defined(ANDROID)
14200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#define MESSAGE_PUMP_UI new base::MessagePumpDefault()
143d5335d37310036a1236ba3f4195afbdc55a85b5aBen Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#elif defined(TOUCH_UI)
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MESSAGE_PUMP_UI new base::MessagePumpGlibX()
14600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#elif defined(OS_NACL)
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Currently NaCl doesn't have a UI or an IO MessageLoop.
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TODO(abarth): Figure out if we need these.
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MESSAGE_PUMP_UI NULL
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MESSAGE_PUMP_IO NULL
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)  // POSIX but not MACOSX.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_UI new base::MessagePumpForUI()
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#error Not implemented
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type_ == TYPE_UI) {
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pump_ = MESSAGE_PUMP_UI;
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else if (type_ == TYPE_IO) {
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pump_ = MESSAGE_PUMP_IO;
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(TYPE_DEFAULT, type_);
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pump_ = new base::MessagePumpDefault();
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMessageLoop::~MessageLoop() {
1704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK_EQ(this, current());
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!state_);
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Clean up any unprocessed tasks, but take care: deleting a task could
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // result in the addition of more tasks (e.g., via DeleteSoon).  We set a
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // limit on the number of times we will allow a deleted task to generate more
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // tasks.  Normally, we should only pass through this loop once or twice.  If
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // we end up hitting the loop limit, then it is probably due to one task that
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is being stubborn.  Inspect the queues to see who is left.
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_work;
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < 100; ++i) {
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DeletePendingTasks();
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReloadWorkQueue();
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // If we end up with empty queues, then break out of the loop.
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    did_work = DeletePendingTasks();
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!did_work)
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!did_work);
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
191201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Let interested parties have one last shot at accessing this.
192201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FOR_EACH_OBSERVER(DestructionObserver, destruction_observers_,
193201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                    WillDestroyCurrentMessageLoop());
194201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // OK, now make it so that no one can find us.
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  lazy_tls_ptr.Pointer()->Set(NULL);
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// static
2003f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenMessageLoop* MessageLoop::current() {
2013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // TODO(darin): sadly, we cannot enable this yet since people call us even
2023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // when they have no intention of using us.
2033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // DCHECK(loop) << "Ouch, did you forget to initialize me?";
2043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return lazy_tls_ptr.Pointer()->Get();
2053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// static
2083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::EnableHistogrammer(bool enable) {
2093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  enable_histogrammer_ = enable;
2103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MessageLoop::AddDestructionObserver(
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DestructionObserver* destruction_observer) {
2144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK_EQ(this, current());
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  destruction_observers_.AddObserver(destruction_observer);
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MessageLoop::RemoveDestructionObserver(
2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DestructionObserver* destruction_observer) {
2204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK_EQ(this, current());
2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  destruction_observers_.RemoveObserver(destruction_observer);
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostTask(
2253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task) {
2263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PostTask_Helper(from_here, task, 0, true);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostDelayedTask(
2303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task, int64 delay_ms) {
2313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PostTask_Helper(from_here, task, delay_ms, true);
2323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostNonNestableTask(
2353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task) {
2363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PostTask_Helper(from_here, task, 0, false);
2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostNonNestableDelayedTask(
2403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task, int64 delay_ms) {
2413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PostTask_Helper(from_here, task, delay_ms, false);
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::Run() {
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AutoRunState save_state(this);
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunHandler();
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::RunAllPending() {
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AutoRunState save_state(this);
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state_->quit_received = true;  // Means run until we would otherwise block.
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunHandler();
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::Quit() {
2563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_EQ(this, current());
2573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (state_) {
2583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    state_->quit_received = true;
2593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else {
2603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    NOTREACHED() << "Must be inside Run to call Quit";
2613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::QuitNow() {
2653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_EQ(this, current());
2663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (state_) {
2673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pump_->Quit();
2683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else {
2693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    NOTREACHED() << "Must be inside Run to call Quit";
2703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::SetNestableTasksAllowed(bool allowed) {
2743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (nestable_tasks_allowed_ != allowed) {
2753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    nestable_tasks_allowed_ = allowed;
2763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!nestable_tasks_allowed_)
2773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return;
2783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Start the native pump if we are not already pumping.
2793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pump_->ScheduleWork();
2803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool MessageLoop::NestableTasksAllowed() const {
2843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return nestable_tasks_allowed_;
2853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool MessageLoop::IsNested() {
2883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return state_->run_depth > 1;
2893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::AddTaskObserver(TaskObserver* task_observer) {
2923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_EQ(this, current());
2933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  task_observers_.AddObserver(task_observer);
2943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) {
2973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_EQ(this, current());
2983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  task_observers_.RemoveObserver(task_observer);
2993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
3003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MessageLoop::AssertIdle() const {
30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We only check |incoming_queue_|, since we don't want to lock |work_queue_|.
30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock lock(incoming_queue_lock_);
30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(incoming_queue_.empty());
30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen//------------------------------------------------------------------------------
3083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Runs the loop in two different SEH modes:
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// enable_SEH_restoration_ = false : any unhandled exception goes to the last
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// one that calls SetUnhandledExceptionFilter().
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// enable_SEH_restoration_ = true : any unhandled exception goes to the filter
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// that was existed before the loop was run.
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::RunHandler() {
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (exception_restoration_) {
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RunInternalInSEHFrame();
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunInternal();
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott__declspec(noinline) void MessageLoop::RunInternalInSEHFrame() {
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  LPTOP_LEVEL_EXCEPTION_FILTER current_filter = GetTopSEHFilter();
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  __try {
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RunInternal();
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } __except(SEHFilter(current_filter)) {
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return;
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::RunInternal() {
3374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK_EQ(this, current());
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3391391b24619d56bae6ce14bb54ed0fb16a945e853Kristian Monsen#ifndef ANDROID
3401391b24619d56bae6ce14bb54ed0fb16a945e853Kristian Monsen  StartHistogrammer();
3411391b24619d56bae6ce14bb54ed0fb16a945e853Kristian Monsen#endif
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_MACOSX)
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (state_->dispatcher && type() == TYPE_UI) {
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    static_cast<base::MessagePumpForUI*>(pump_.get())->
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        RunWithDispatcher(this, state_->dispatcher);
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_->Run(this);
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::ProcessNextDelayedNonNestableTask() {
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (state_->run_depth != 1)
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (deferred_non_nestable_work_queue_.empty())
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Task* task = deferred_non_nestable_work_queue_.front().task;
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  deferred_non_nestable_work_queue_.pop();
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTask(task);
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::RunTask(Task* task) {
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(nestable_tasks_allowed_);
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Execute the task and assume the worst: It is probably not reentrant.
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  nestable_tasks_allowed_ = false;
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  HistogramEvent(kTaskRunEvent);
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FOR_EACH_OBSERVER(TaskObserver, task_observers_,
375513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                    WillProcessTask(task));
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  task->Run();
377513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  FOR_EACH_OBSERVER(TaskObserver, task_observers_, DidProcessTask(task));
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete task;
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  nestable_tasks_allowed_ = true;
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) {
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (pending_task.nestable || state_->run_depth == 1) {
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RunTask(pending_task.task);
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Show that we ran a task (Note: a new one might arrive as a
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // consequence!).
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We couldn't run the task now because we're in a nested message loop
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and the task isn't nestable.
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  deferred_non_nestable_work_queue_.push(pending_task);
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::AddToDelayedWorkQueue(const PendingTask& pending_task) {
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Move to the delayed work queue.  Initialize the sequence number
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // before inserting into the delayed_work_queue_.  The sequence number
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is used to faciliate FIFO sorting when two tasks have the same
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // delayed_run_time value.
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PendingTask new_pending_task(pending_task);
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  new_pending_task.sequence_num = next_sequence_num_++;
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delayed_work_queue_.push(new_pending_task);
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::ReloadWorkQueue() {
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We can improve performance of our loading tasks from incoming_queue_ to
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // work_queue_ by waiting until the last minute (work_queue_ is empty) to
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // load.  That reduces the number of locks-per-task significantly when our
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // queues get large.
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!work_queue_.empty())
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;  // Wait till we *really* need to lock and load.
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Acquire all we can from the inter-thread queue with one lock acquisition.
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
41772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::AutoLock lock(incoming_queue_lock_);
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (incoming_queue_.empty())
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return;
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    incoming_queue_.Swap(&work_queue_);  // Constant time
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(incoming_queue_.empty());
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::DeletePendingTasks() {
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_work = !work_queue_.empty();
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (!work_queue_.empty()) {
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    PendingTask pending_task = work_queue_.front();
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    work_queue_.pop();
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!pending_task.delayed_run_time.is_null()) {
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // We want to delete delayed tasks in the same order in which they would
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // normally be deleted in case of any funny dependencies between delayed
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // tasks.
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      AddToDelayedWorkQueue(pending_task);
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else {
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // TODO(darin): Delete all tasks once it is safe to do so.
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // Until it is totally safe, just do it when running Purify or
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // Valgrind.
439513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(PURIFY) || defined(USE_HEAPCHECKER)
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete pending_task.task;
4413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#else
4423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      if (RunningOnValgrind())
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        delete pending_task.task;
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // defined(OS_POSIX)
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  did_work |= !deferred_non_nestable_work_queue_.empty();
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (!deferred_non_nestable_work_queue_.empty()) {
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // TODO(darin): Delete all tasks once it is safe to do so.
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Until it is totaly safe, only delete them under Purify and Valgrind.
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Task* task = NULL;
452513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(PURIFY) || defined(USE_HEAPCHECKER)
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    task = deferred_non_nestable_work_queue_.front().task;
4543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#else
4553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (RunningOnValgrind())
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      task = deferred_non_nestable_work_queue_.front().task;
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    deferred_non_nestable_work_queue_.pop();
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (task)
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete task;
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  did_work |= !delayed_work_queue_.empty();
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (!delayed_work_queue_.empty()) {
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Task* task = delayed_work_queue_.top().task;
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delayed_work_queue_.pop();
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete task;
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return did_work;
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Possibly called on a background thread!
4723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostTask_Helper(
4733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task, int64 delay_ms,
4743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    bool nestable) {
4753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  task->SetBirthPlace(from_here);
4763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PendingTask pending_task(task, nestable);
4783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (delay_ms > 0) {
4803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pending_task.delayed_run_time =
4813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        TimeTicks::Now() + TimeDelta::FromMilliseconds(delay_ms);
4823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(OS_WIN)
4843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (high_resolution_timer_expiration_.is_null()) {
4853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // Windows timers are granular to 15.6ms.  If we only set high-res
4863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // timers for those under 15.6ms, then a 18ms timer ticks at ~32ms,
4873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // which as a percentage is pretty inaccurate.  So enable high
4883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // res timers for any timer which is within 2x of the granularity.
4893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // This is a tradeoff between accuracy and power management.
4903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      bool needs_high_res_timers =
4913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          delay_ms < (2 * base::Time::kMinLowResolutionThresholdMs);
4923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      if (needs_high_res_timers) {
4933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        base::Time::ActivateHighResolutionTimer(true);
4943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        high_resolution_timer_expiration_ = TimeTicks::Now() +
4953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            TimeDelta::FromMilliseconds(kHighResolutionTimerModeLeaseTimeMs);
4963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      }
4973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
4983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif
4993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else {
5003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    DCHECK_EQ(delay_ms, 0) << "delay should not be negative";
5013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
5023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(OS_WIN)
5043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!high_resolution_timer_expiration_.is_null()) {
5053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (TimeTicks::Now() > high_resolution_timer_expiration_) {
5063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      base::Time::ActivateHighResolutionTimer(false);
5073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      high_resolution_timer_expiration_ = TimeTicks();
5083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
5093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
5103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif
5113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Warning: Don't try to short-circuit, and handle this thread's tasks more
5133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // directly, as it could starve handling of foreign threads.  Put every task
5143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // into this queue.
5153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  scoped_refptr<base::MessagePump> pump;
5173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  {
51872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::AutoLock locked(incoming_queue_lock_);
5193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    bool was_empty = incoming_queue_.empty();
5213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    incoming_queue_.push(pending_task);
5223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!was_empty)
5233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return;  // Someone else should have started the sub-pump.
5243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pump = pump_;
5263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
5273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Since the incoming_queue_ may contain a task that destroys this message
5283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // loop, we cannot exit incoming_queue_lock_ until we are done with |this|.
5293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // We use a stack-based reference to the message pump so that we can call
5303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // ScheduleWork outside of incoming_queue_lock_.
5313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  pump->ScheduleWork();
5333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
5343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen//------------------------------------------------------------------------------
5363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Method and data for histogramming events and actions taken by each instance
5373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// on each thread.
5383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::StartHistogrammer() {
540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (enable_histogrammer_ && !message_histogram_
5413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      && base::StatisticsRecorder::IsActive()) {
5423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    DCHECK(!thread_name_.empty());
5433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    message_histogram_ = base::LinearHistogram::FactoryGet(
5443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        "MsgLoop:" + thread_name_,
5453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        kLeastNonZeroMessageId, kMaxMessageId,
5463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        kNumberOfDistinctMessagesDisplayed,
5473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        message_histogram_->kHexRangePrintingFlag);
5483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    message_histogram_->SetRangeDescriptions(event_descriptions_);
5493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
5503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
5513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::HistogramEvent(int event) {
553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (message_histogram_)
5543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    message_histogram_->Add(event);
5553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
5563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::DoWork() {
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!nestable_tasks_allowed_) {
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Task can't be executed right now.
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (;;) {
564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReloadWorkQueue();
565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (work_queue_.empty())
566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Execute oldest task.
569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    do {
570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      PendingTask pending_task = work_queue_.front();
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      work_queue_.pop();
572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (!pending_task.delayed_run_time.is_null()) {
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        AddToDelayedWorkQueue(pending_task);
574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // If we changed the topmost task, then it is time to re-schedule.
575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (delayed_work_queue_.top().task == pending_task.task)
576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          pump_->ScheduleDelayedWork(pending_task.delayed_run_time);
577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      } else {
578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (DeferOrRunPendingTask(pending_task))
579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          return true;
580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } while (!work_queue_.empty());
582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Nothing happened.
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
588513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool MessageLoop::DoDelayedWork(base::TimeTicks* next_delayed_work_time) {
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) {
590513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    recent_time_ = *next_delayed_work_time = TimeTicks();
591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
594513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // When we "fall behind," there will be a lot of tasks in the delayed work
595513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // queue that are ready to run.  To increase efficiency when we fall behind,
596513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // we will only call Time::Now() intermittently, and then process all tasks
597513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // that are ready to run before calling it again.  As a result, the more we
598513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // fall behind (and have a lot of ready-to-run delayed tasks), the more
599513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // efficient we'll be at handling the tasks.
600513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
601513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time;
602513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (next_run_time > recent_time_) {
603513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    recent_time_ = TimeTicks::Now();  // Get a better view of Now();
604513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (next_run_time > recent_time_) {
605513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      *next_delayed_work_time = next_run_time;
606513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return false;
607513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PendingTask pending_task = delayed_work_queue_.top();
611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delayed_work_queue_.pop();
612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!delayed_work_queue_.empty())
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time;
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return DeferOrRunPendingTask(pending_task);
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::DoIdleWork() {
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (ProcessNextDelayedNonNestableTask())
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (state_->quit_received)
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pump_->Quit();
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoop::AutoRunState
631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) {
633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make the loop reference us.
634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  previous_state_ = loop_->state_;
635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (previous_state_) {
636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    run_depth = previous_state_->run_depth + 1;
637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    run_depth = 1;
639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  loop_->state_ = this;
641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize the other fields:
643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  quit_received = false;
644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_MACOSX)
645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  dispatcher = NULL;
646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMessageLoop::AutoRunState::~AutoRunState() {
650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  loop_->state_ = previous_state_;
651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoop::PendingTask
655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::PendingTask::operator<(const PendingTask& other) const {
657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Since the top of a priority queue is defined as the "greatest" element, we
658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // need to invert the comparison here.  We want the smaller time to be at the
659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // top of the heap.
660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (delayed_run_time < other.delayed_run_time)
662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (delayed_run_time > other.delayed_run_time)
665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If the times happen to match, then we use the sequence number to decide.
668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Compare the difference to support integer roll-over.
669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (sequence_num - other.sequence_num) > 0;
670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoopForUI
674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForUI::DidProcessMessage(const MSG& message) {
677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_win()->DidProcessMessage(message);
678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // defined(OS_WIN)
680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
681dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(USE_X11)
682dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenDisplay* MessageLoopForUI::GetDisplay() {
683dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return gdk_x11_get_default_xdisplay();
684dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
685dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif  // defined(USE_X11)
686dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
687e4feccc6428acb735e68c15bcf972504a705c547Kristian Monsen#if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(ANDROID)
688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForUI::AddObserver(Observer* observer) {
689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_ui()->AddObserver(observer);
690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForUI::RemoveObserver(Observer* observer) {
693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_ui()->RemoveObserver(observer);
694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForUI::Run(Dispatcher* dispatcher) {
697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AutoRunState save_state(this);
698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state_->dispatcher = dispatcher;
699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunHandler();
700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
70121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif  // !defined(OS_MACOSX) && !defined(OS_NACL)
702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoopForIO
705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForIO::RegisterIOHandler(HANDLE file, IOHandler* handler) {
709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_io()->RegisterIOHandler(file, handler);
710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoopForIO::WaitForIOCompletion(DWORD timeout, IOHandler* filter) {
713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return pump_io()->WaitForIOCompletion(timeout, filter);
714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
71621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#elif defined(OS_POSIX) && !defined(OS_NACL)
717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoopForIO::WatchFileDescriptor(int fd,
719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           bool persistent,
720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           Mode mode,
721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           FileDescriptorWatcher *controller,
722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           Watcher *delegate) {
723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return pump_libevent()->WatchFileDescriptor(
724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      fd,
725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      persistent,
726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      static_cast<base::MessagePumpLibevent::Mode>(mode),
727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      controller,
728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delegate);
729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
732