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