message_loop.cc revision e4feccc6428acb735e68c15bcf972504a705c547
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 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
7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_POSIX) && !defined(OS_MACOSX)
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),
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      state_(NULL),
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      next_sequence_num_(0) {
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!current()) << "should only have one message loop per thread";
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  lazy_tls_ptr.Pointer()->Set(this);
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(rvargas): Get rid of the OS guards.
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_UI new base::MessagePumpForUI()
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpForIO()
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_UI base::MessagePumpMac::Create()
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
13700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#elif defined(ANDROID)
13800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#define MESSAGE_PUMP_UI new base::MessagePumpDefault()
139d5335d37310036a1236ba3f4195afbdc55a85b5aBen Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
140513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#elif defined(TOUCH_UI)
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MESSAGE_PUMP_UI new base::MessagePumpGlibX()
14200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#elif defined(OS_NACL)
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Currently NaCl doesn't have a UI or an IO MessageLoop.
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TODO(abarth): Figure out if we need these.
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MESSAGE_PUMP_UI NULL
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define MESSAGE_PUMP_IO NULL
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)  // POSIX but not MACOSX.
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_UI new base::MessagePumpForUI()
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MESSAGE_PUMP_IO new base::MessagePumpLibevent()
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#error Not implemented
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type_ == TYPE_UI) {
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pump_ = MESSAGE_PUMP_UI;
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else if (type_ == TYPE_IO) {
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pump_ = MESSAGE_PUMP_IO;
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(TYPE_DEFAULT, type_);
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pump_ = new base::MessagePumpDefault();
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMessageLoop::~MessageLoop() {
1664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK_EQ(this, current());
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!state_);
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Clean up any unprocessed tasks, but take care: deleting a task could
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // result in the addition of more tasks (e.g., via DeleteSoon).  We set a
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // limit on the number of times we will allow a deleted task to generate more
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // tasks.  Normally, we should only pass through this loop once or twice.  If
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // we end up hitting the loop limit, then it is probably due to one task that
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is being stubborn.  Inspect the queues to see who is left.
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_work;
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < 100; ++i) {
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DeletePendingTasks();
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReloadWorkQueue();
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // If we end up with empty queues, then break out of the loop.
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    did_work = DeletePendingTasks();
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!did_work)
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!did_work);
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
187201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Let interested parties have one last shot at accessing this.
188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FOR_EACH_OBSERVER(DestructionObserver, destruction_observers_,
189201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                    WillDestroyCurrentMessageLoop());
190201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // OK, now make it so that no one can find us.
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  lazy_tls_ptr.Pointer()->Set(NULL);
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// static
1963f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenMessageLoop* MessageLoop::current() {
1973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // TODO(darin): sadly, we cannot enable this yet since people call us even
1983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // when they have no intention of using us.
1993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // DCHECK(loop) << "Ouch, did you forget to initialize me?";
2003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return lazy_tls_ptr.Pointer()->Get();
2013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// static
2043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::EnableHistogrammer(bool enable) {
2053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  enable_histogrammer_ = enable;
2063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MessageLoop::AddDestructionObserver(
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DestructionObserver* destruction_observer) {
2104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK_EQ(this, current());
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  destruction_observers_.AddObserver(destruction_observer);
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MessageLoop::RemoveDestructionObserver(
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DestructionObserver* destruction_observer) {
2164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK_EQ(this, current());
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  destruction_observers_.RemoveObserver(destruction_observer);
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostTask(
2213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task) {
2223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PostTask_Helper(from_here, task, 0, true);
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostDelayedTask(
2263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task, int64 delay_ms) {
2273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PostTask_Helper(from_here, task, delay_ms, true);
2283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostNonNestableTask(
2313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task) {
2323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PostTask_Helper(from_here, task, 0, false);
2333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostNonNestableDelayedTask(
2363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task, int64 delay_ms) {
2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PostTask_Helper(from_here, task, delay_ms, false);
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::Run() {
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AutoRunState save_state(this);
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunHandler();
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::RunAllPending() {
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AutoRunState save_state(this);
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state_->quit_received = true;  // Means run until we would otherwise block.
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunHandler();
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::Quit() {
2523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_EQ(this, current());
2533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (state_) {
2543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    state_->quit_received = true;
2553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else {
2563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    NOTREACHED() << "Must be inside Run to call Quit";
2573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::QuitNow() {
2613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_EQ(this, current());
2623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (state_) {
2633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pump_->Quit();
2643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else {
2653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    NOTREACHED() << "Must be inside Run to call Quit";
2663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::SetNestableTasksAllowed(bool allowed) {
2703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (nestable_tasks_allowed_ != allowed) {
2713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    nestable_tasks_allowed_ = allowed;
2723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!nestable_tasks_allowed_)
2733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return;
2743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Start the native pump if we are not already pumping.
2753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pump_->ScheduleWork();
2763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool MessageLoop::NestableTasksAllowed() const {
2803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return nestable_tasks_allowed_;
2813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool MessageLoop::IsNested() {
2843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return state_->run_depth > 1;
2853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::AddTaskObserver(TaskObserver* task_observer) {
2883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_EQ(this, current());
2893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  task_observers_.AddObserver(task_observer);
2903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) {
2933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_EQ(this, current());
2943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  task_observers_.RemoveObserver(task_observer);
2953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
2963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MessageLoop::AssertIdle() const {
29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We only check |incoming_queue_|, since we don't want to lock |work_queue_|.
29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock lock(incoming_queue_lock_);
30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(incoming_queue_.empty());
30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen//------------------------------------------------------------------------------
3043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Runs the loop in two different SEH modes:
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// enable_SEH_restoration_ = false : any unhandled exception goes to the last
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// one that calls SetUnhandledExceptionFilter().
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// enable_SEH_restoration_ = true : any unhandled exception goes to the filter
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// that was existed before the loop was run.
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::RunHandler() {
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (exception_restoration_) {
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RunInternalInSEHFrame();
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunInternal();
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
3203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott__declspec(noinline) void MessageLoop::RunInternalInSEHFrame() {
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  LPTOP_LEVEL_EXCEPTION_FILTER current_filter = GetTopSEHFilter();
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  __try {
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RunInternal();
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } __except(SEHFilter(current_filter)) {
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return;
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::RunInternal() {
3334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK_EQ(this, current());
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3351391b24619d56bae6ce14bb54ed0fb16a945e853Kristian Monsen#ifndef ANDROID
3361391b24619d56bae6ce14bb54ed0fb16a945e853Kristian Monsen  StartHistogrammer();
3371391b24619d56bae6ce14bb54ed0fb16a945e853Kristian Monsen#endif
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_MACOSX)
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (state_->dispatcher && type() == TYPE_UI) {
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    static_cast<base::MessagePumpForUI*>(pump_.get())->
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        RunWithDispatcher(this, state_->dispatcher);
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_->Run(this);
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::ProcessNextDelayedNonNestableTask() {
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (state_->run_depth != 1)
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (deferred_non_nestable_work_queue_.empty())
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Task* task = deferred_non_nestable_work_queue_.front().task;
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  deferred_non_nestable_work_queue_.pop();
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTask(task);
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::RunTask(Task* task) {
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(nestable_tasks_allowed_);
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Execute the task and assume the worst: It is probably not reentrant.
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  nestable_tasks_allowed_ = false;
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  HistogramEvent(kTaskRunEvent);
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FOR_EACH_OBSERVER(TaskObserver, task_observers_,
371513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                    WillProcessTask(task));
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  task->Run();
373513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  FOR_EACH_OBSERVER(TaskObserver, task_observers_, DidProcessTask(task));
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete task;
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  nestable_tasks_allowed_ = true;
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) {
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (pending_task.nestable || state_->run_depth == 1) {
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RunTask(pending_task.task);
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Show that we ran a task (Note: a new one might arrive as a
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // consequence!).
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We couldn't run the task now because we're in a nested message loop
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and the task isn't nestable.
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  deferred_non_nestable_work_queue_.push(pending_task);
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::AddToDelayedWorkQueue(const PendingTask& pending_task) {
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Move to the delayed work queue.  Initialize the sequence number
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // before inserting into the delayed_work_queue_.  The sequence number
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is used to faciliate FIFO sorting when two tasks have the same
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // delayed_run_time value.
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PendingTask new_pending_task(pending_task);
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  new_pending_task.sequence_num = next_sequence_num_++;
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delayed_work_queue_.push(new_pending_task);
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoop::ReloadWorkQueue() {
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We can improve performance of our loading tasks from incoming_queue_ to
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // work_queue_ by waiting until the last minute (work_queue_ is empty) to
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // load.  That reduces the number of locks-per-task significantly when our
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // queues get large.
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!work_queue_.empty())
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;  // Wait till we *really* need to lock and load.
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Acquire all we can from the inter-thread queue with one lock acquisition.
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
41372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::AutoLock lock(incoming_queue_lock_);
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (incoming_queue_.empty())
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return;
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    incoming_queue_.Swap(&work_queue_);  // Constant time
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(incoming_queue_.empty());
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::DeletePendingTasks() {
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_work = !work_queue_.empty();
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (!work_queue_.empty()) {
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    PendingTask pending_task = work_queue_.front();
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    work_queue_.pop();
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!pending_task.delayed_run_time.is_null()) {
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // We want to delete delayed tasks in the same order in which they would
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // normally be deleted in case of any funny dependencies between delayed
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // tasks.
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      AddToDelayedWorkQueue(pending_task);
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else {
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // TODO(darin): Delete all tasks once it is safe to do so.
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // Until it is totally safe, just do it when running Purify or
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // Valgrind.
435513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(PURIFY) || defined(USE_HEAPCHECKER)
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete pending_task.task;
4373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#else
4383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      if (RunningOnValgrind())
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        delete pending_task.task;
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // defined(OS_POSIX)
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  did_work |= !deferred_non_nestable_work_queue_.empty();
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (!deferred_non_nestable_work_queue_.empty()) {
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // TODO(darin): Delete all tasks once it is safe to do so.
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Until it is totaly safe, only delete them under Purify and Valgrind.
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Task* task = NULL;
448513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(PURIFY) || defined(USE_HEAPCHECKER)
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    task = deferred_non_nestable_work_queue_.front().task;
4503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#else
4513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (RunningOnValgrind())
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      task = deferred_non_nestable_work_queue_.front().task;
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    deferred_non_nestable_work_queue_.pop();
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (task)
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delete task;
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  did_work |= !delayed_work_queue_.empty();
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (!delayed_work_queue_.empty()) {
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Task* task = delayed_work_queue_.top().task;
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delayed_work_queue_.pop();
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete task;
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return did_work;
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Possibly called on a background thread!
4683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::PostTask_Helper(
4693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    const tracked_objects::Location& from_here, Task* task, int64 delay_ms,
4703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    bool nestable) {
4713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  task->SetBirthPlace(from_here);
4723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  PendingTask pending_task(task, nestable);
4743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (delay_ms > 0) {
4763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pending_task.delayed_run_time =
4773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        TimeTicks::Now() + TimeDelta::FromMilliseconds(delay_ms);
4783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(OS_WIN)
4803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (high_resolution_timer_expiration_.is_null()) {
4813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // Windows timers are granular to 15.6ms.  If we only set high-res
4823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // timers for those under 15.6ms, then a 18ms timer ticks at ~32ms,
4833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // which as a percentage is pretty inaccurate.  So enable high
4843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // res timers for any timer which is within 2x of the granularity.
4853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      // This is a tradeoff between accuracy and power management.
4863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      bool needs_high_res_timers =
4873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          delay_ms < (2 * base::Time::kMinLowResolutionThresholdMs);
4883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      if (needs_high_res_timers) {
4893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        base::Time::ActivateHighResolutionTimer(true);
4903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        high_resolution_timer_expiration_ = TimeTicks::Now() +
4913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            TimeDelta::FromMilliseconds(kHighResolutionTimerModeLeaseTimeMs);
4923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      }
4933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
4943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif
4953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else {
4963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    DCHECK_EQ(delay_ms, 0) << "delay should not be negative";
4973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
4983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(OS_WIN)
5003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!high_resolution_timer_expiration_.is_null()) {
5013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (TimeTicks::Now() > high_resolution_timer_expiration_) {
5023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      base::Time::ActivateHighResolutionTimer(false);
5033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      high_resolution_timer_expiration_ = TimeTicks();
5043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
5053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
5063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif
5073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Warning: Don't try to short-circuit, and handle this thread's tasks more
5093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // directly, as it could starve handling of foreign threads.  Put every task
5103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // into this queue.
5113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  scoped_refptr<base::MessagePump> pump;
5133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  {
51472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::AutoLock locked(incoming_queue_lock_);
5153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    bool was_empty = incoming_queue_.empty();
5173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    incoming_queue_.push(pending_task);
5183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!was_empty)
5193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return;  // Someone else should have started the sub-pump.
5203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pump = pump_;
5223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
5233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Since the incoming_queue_ may contain a task that destroys this message
5243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // loop, we cannot exit incoming_queue_lock_ until we are done with |this|.
5253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // We use a stack-based reference to the message pump so that we can call
5263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // ScheduleWork outside of incoming_queue_lock_.
5273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  pump->ScheduleWork();
5293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
5303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen//------------------------------------------------------------------------------
5323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Method and data for histogramming events and actions taken by each instance
5333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// on each thread.
5343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::StartHistogrammer() {
5363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (enable_histogrammer_ && !message_histogram_.get()
5373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      && base::StatisticsRecorder::IsActive()) {
5383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    DCHECK(!thread_name_.empty());
5393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    message_histogram_ = base::LinearHistogram::FactoryGet(
5403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        "MsgLoop:" + thread_name_,
5413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        kLeastNonZeroMessageId, kMaxMessageId,
5423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        kNumberOfDistinctMessagesDisplayed,
5433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        message_histogram_->kHexRangePrintingFlag);
5443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    message_histogram_->SetRangeDescriptions(event_descriptions_);
5453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
5463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
5473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
5483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MessageLoop::HistogramEvent(int event) {
5493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (message_histogram_.get())
5503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    message_histogram_->Add(event);
5513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
5523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::DoWork() {
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!nestable_tasks_allowed_) {
555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Task can't be executed right now.
556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (;;) {
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ReloadWorkQueue();
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (work_queue_.empty())
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Execute oldest task.
565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    do {
566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      PendingTask pending_task = work_queue_.front();
567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      work_queue_.pop();
568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (!pending_task.delayed_run_time.is_null()) {
569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        AddToDelayedWorkQueue(pending_task);
570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // If we changed the topmost task, then it is time to re-schedule.
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (delayed_work_queue_.top().task == pending_task.task)
572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          pump_->ScheduleDelayedWork(pending_task.delayed_run_time);
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      } else {
574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (DeferOrRunPendingTask(pending_task))
575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          return true;
576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } while (!work_queue_.empty());
578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Nothing happened.
581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
584513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool MessageLoop::DoDelayedWork(base::TimeTicks* next_delayed_work_time) {
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) {
586513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    recent_time_ = *next_delayed_work_time = TimeTicks();
587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
590513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // When we "fall behind," there will be a lot of tasks in the delayed work
591513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // queue that are ready to run.  To increase efficiency when we fall behind,
592513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // we will only call Time::Now() intermittently, and then process all tasks
593513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // that are ready to run before calling it again.  As a result, the more we
594513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // fall behind (and have a lot of ready-to-run delayed tasks), the more
595513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // efficient we'll be at handling the tasks.
596513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
597513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time;
598513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (next_run_time > recent_time_) {
599513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    recent_time_ = TimeTicks::Now();  // Get a better view of Now();
600513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (next_run_time > recent_time_) {
601513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      *next_delayed_work_time = next_run_time;
602513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return false;
603513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PendingTask pending_task = delayed_work_queue_.top();
607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delayed_work_queue_.pop();
608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!delayed_work_queue_.empty())
610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time;
611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return DeferOrRunPendingTask(pending_task);
613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::DoIdleWork() {
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (ProcessNextDelayedNonNestableTask())
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (state_->quit_received)
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pump_->Quit();
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return false;
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoop::AutoRunState
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) {
629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make the loop reference us.
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  previous_state_ = loop_->state_;
631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (previous_state_) {
632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    run_depth = previous_state_->run_depth + 1;
633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    run_depth = 1;
635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  loop_->state_ = this;
637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize the other fields:
639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  quit_received = false;
640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_MACOSX)
641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  dispatcher = NULL;
642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMessageLoop::AutoRunState::~AutoRunState() {
646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  loop_->state_ = previous_state_;
647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoop::PendingTask
651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoop::PendingTask::operator<(const PendingTask& other) const {
653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Since the top of a priority queue is defined as the "greatest" element, we
654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // need to invert the comparison here.  We want the smaller time to be at the
655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // top of the heap.
656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (delayed_run_time < other.delayed_run_time)
658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (delayed_run_time > other.delayed_run_time)
661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If the times happen to match, then we use the sequence number to decide.
664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Compare the difference to support integer roll-over.
665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (sequence_num - other.sequence_num) > 0;
666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoopForUI
670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForUI::DidProcessMessage(const MSG& message) {
673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_win()->DidProcessMessage(message);
674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // defined(OS_WIN)
676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
677dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(USE_X11)
678dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenDisplay* MessageLoopForUI::GetDisplay() {
679dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return gdk_x11_get_default_xdisplay();
680dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
681dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif  // defined(USE_X11)
682dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
683e4feccc6428acb735e68c15bcf972504a705c547Kristian Monsen#if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(ANDROID)
684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForUI::AddObserver(Observer* observer) {
685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_ui()->AddObserver(observer);
686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForUI::RemoveObserver(Observer* observer) {
689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_ui()->RemoveObserver(observer);
690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForUI::Run(Dispatcher* dispatcher) {
693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AutoRunState save_state(this);
694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state_->dispatcher = dispatcher;
695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunHandler();
696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
69721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif  // !defined(OS_MACOSX) && !defined(OS_NACL)
698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoopForIO
701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MessageLoopForIO::RegisterIOHandler(HANDLE file, IOHandler* handler) {
705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pump_io()->RegisterIOHandler(file, handler);
706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoopForIO::WaitForIOCompletion(DWORD timeout, IOHandler* filter) {
709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return pump_io()->WaitForIOCompletion(timeout, filter);
710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
71221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#elif defined(OS_POSIX) && !defined(OS_NACL)
713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MessageLoopForIO::WatchFileDescriptor(int fd,
715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           bool persistent,
716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           Mode mode,
717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           FileDescriptorWatcher *controller,
718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           Watcher *delegate) {
719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return pump_libevent()->WatchFileDescriptor(
720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      fd,
721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      persistent,
722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      static_cast<base::MessagePumpLibevent::Mode>(mode),
723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      controller,
724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      delegate);
725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
728