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