17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/alias.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_default.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/statistics_recorder.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/run_loop.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/third_party/dynamic_annotations/dynamic_annotations.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_local.h" 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_mac.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_IOS) 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_libevent.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_android.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdk.h> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdkx.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace base { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A lazily created thread local storage for quick access to a thread's message 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// loop, if one exists. This should be safe and free of static constructors. 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)LazyInstance<base::ThreadLocalPointer<MessageLoop> >::Leaky lazy_tls_ptr = 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Logical events for Histogram profiling. Run with -message-loop-histogrammer 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to get an accounting of messages and actions taken on each thread. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTaskRunEvent = 0x1; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTimerEvent = 0x2; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provide range of message IDs for use in histogramming and debug display. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLeastNonZeroMessageId = 1; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxMessageId = 1099; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNumberOfDistinctMessagesDisplayed = 1100; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provide a macro that takes an expression (such as a constant, or macro 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constant) and creates a pair to initalize an array of pairs. In this case, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// our pair consists of the expressions value, and the "stringized" version 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the expression (i.e., the exrpression put in quotes). For example, if 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we have: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// #define FOO 2 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// #define BAR 5 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then the following: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VALUE_TO_NUMBER_AND_NAME(FOO + BAR) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will expand to: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {7, "FOO + BAR"} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use the resulting array as an argument to our histogram, which reads the 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// number as a bucket identifier, and proceeds to use the corresponding name 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the pair (i.e., the quoted string) when printing out a histogram. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VALUE_TO_NUMBER_AND_NAME(name) {name, #name}, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const LinearHistogram::DescriptionPair event_descriptions_[] = { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Provide some pretty print capability in our histogram for our internal 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A few events we handle (kindred to messages), and used to profile actions. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALUE_TO_NUMBER_AND_NAME(kTimerEvent) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {-1, NULL} // The list must be null terminated, per API to histogram. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool enable_histogrammer_ = false; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Returns true if MessagePump::ScheduleWork() must be called one 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// time for every task that is added to the MessageLoop incoming queue. 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool AlwaysNotifyPump(MessageLoop::Type type) { 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_ANDROID) 95bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return type == MessageLoop::TYPE_UI || type == MessageLoop::TYPE_JAVA; 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#else 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Upon a SEH exception in this thread, it restores the original unhandled 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// exception filter. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetUnhandledExceptionFilter(old_filter); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EXCEPTION_CONTINUE_SEARCH; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Retrieves a pointer to the current unhandled exception filter. There 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is no standalone getter method. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static LPTOP_LEVEL_EXCEPTION_FILTER GetTopSEHFilter() { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LPTOP_LEVEL_EXCEPTION_FILTER top_filter = NULL; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top_filter = ::SetUnhandledExceptionFilter(0); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetUnhandledExceptionFilter(top_filter); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return top_filter; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_WIN) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoop::TaskObserver::TaskObserver() { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoop::TaskObserver::~TaskObserver() { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoop::DestructionObserver::~DestructionObserver() { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoop::MessageLoop(Type type) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : type_(type), 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exception_restoration_(false), 141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch nestable_tasks_allowed_(true), 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_modal_loop_(false), 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch message_histogram_(NULL), 146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch run_loop_(NULL) { 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Init(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pump_.reset(CreateMessagePumpForType(type)); 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MessageLoop::MessageLoop(scoped_ptr<MessagePump> pump) 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : pump_(pump.Pass()), 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type_(TYPE_CUSTOM), 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) exception_restoration_(false), 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) nestable_tasks_allowed_(true), 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) os_modal_loop_(false), 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif // OS_WIN 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_histogram_(NULL), 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) run_loop_(NULL) { 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(pump_.get()); 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Init(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoop::~MessageLoop() { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!run_loop_); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clean up any unprocessed tasks, but take care: deleting a task could 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result in the addition of more tasks (e.g., via DeleteSoon). We set a 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // limit on the number of times we will allow a deleted task to generate more 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tasks. Normally, we should only pass through this loop once or twice. If 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we end up hitting the loop limit, then it is probably due to one task that 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is being stubborn. Inspect the queues to see who is left. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool did_work; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 100; ++i) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeletePendingTasks(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReloadWorkQueue(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we end up with empty queues, then break out of the loop. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_work = DeletePendingTasks(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!did_work) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!did_work); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let interested parties have one last shot at accessing this. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(DestructionObserver, destruction_observers_, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WillDestroyCurrentMessageLoop()); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_task_runner_handle_.reset(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Tell the incoming queue that we are dying. 195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch incoming_task_queue_->WillDestroyCurrentMessageLoop(); 196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch incoming_task_queue_ = NULL; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_proxy_ = NULL; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OK, now make it so that no one can find us. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lazy_tls_ptr.Pointer()->Set(NULL); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoop* MessageLoop::current() { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): sadly, we cannot enable this yet since people call us even 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when they have no intention of using us. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DCHECK(loop) << "Ouch, did you forget to initialize me?"; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return lazy_tls_ptr.Pointer()->Get(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::EnableHistogrammer(bool enable) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enable_histogrammer_ = enable; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MessageLoop::InitMessagePumpForUIFactory(MessagePumpFactory* factory) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (message_pump_for_ui_factory_) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_pump_for_ui_factory_ = factory; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MessagePump* MessageLoop::CreateMessagePumpForType(Type type) { 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TODO(rvargas): Get rid of the OS guards. 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN) 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_UI new MessagePumpForUI() 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_IO new MessagePumpForIO() 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#elif defined(OS_IOS) 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_UI MessagePumpMac::Create() 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_IO new MessagePumpIOSForIO() 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#elif defined(OS_MACOSX) 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_UI MessagePumpMac::Create() 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_IO new MessagePumpLibevent() 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#elif defined(OS_NACL) 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Currently NaCl doesn't have a UI MessageLoop. 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TODO(abarth): Figure out if we need this. 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_UI NULL 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// ipc_channel_nacl.cc uses a worker thread to do socket reads currently, and 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// doesn't require extra support for watching file descriptors. 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_IO new MessagePumpDefault() 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#elif defined(OS_POSIX) // POSIX but not MACOSX. 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_UI new MessagePumpForUI() 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MESSAGE_PUMP_IO new MessagePumpLibevent() 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#error Not implemented 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type == MessageLoop::TYPE_UI) { 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (message_pump_for_ui_factory_) 253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return message_pump_for_ui_factory_(); 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return MESSAGE_PUMP_UI; 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type == MessageLoop::TYPE_IO) 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return MESSAGE_PUMP_IO; 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(TOOLKIT_GTK) 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type == MessageLoop::TYPE_GPU) 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return new MessagePumpX11(); 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID) 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type == MessageLoop::TYPE_JAVA) 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return MESSAGE_PUMP_UI; 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(MessageLoop::TYPE_DEFAULT, type); 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return new MessagePumpDefault(); 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::AddDestructionObserver( 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestructionObserver* destruction_observer) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destruction_observers_.AddObserver(destruction_observer); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::RemoveDestructionObserver( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestructionObserver* destruction_observer) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destruction_observers_.RemoveObserver(destruction_observer); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::PostTask( 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task) { 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!task.is_null()) << from_here.ToString(); 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch incoming_task_queue_->AddToIncomingQueue(from_here, task, TimeDelta(), true); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MessageLoop::TryPostTask( 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const tracked_objects::Location& from_here, 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!task.is_null()) << from_here.ToString(); 293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return incoming_task_queue_->TryAddToIncomingQueue(from_here, task); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::PostDelayedTask( 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta delay) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!task.is_null()) << from_here.ToString(); 301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, true); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::PostNonNestableTask( 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!task.is_null()) << from_here.ToString(); 308ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch incoming_task_queue_->AddToIncomingQueue(from_here, task, TimeDelta(), false); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::PostNonNestableDelayedTask( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Closure& task, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta delay) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!task.is_null()) << from_here.ToString(); 316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, false); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::Run() { 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RunLoop run_loop; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_loop.Run(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::RunUntilIdle() { 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RunLoop run_loop; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_loop.RunUntilIdle(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::QuitWhenIdle() { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (run_loop_) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_loop_->quit_when_idle_received_ = true; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Must be inside Run to call Quit"; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::QuitNow() { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (run_loop_) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_->Quit(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Must be inside Run to call Quit"; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::IsType(Type type) const { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type_ == type; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void QuitCurrentWhenIdle() { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop::current()->QuitWhenIdle(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Closure MessageLoop::QuitWhenIdleClosure() { 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Bind(&QuitCurrentWhenIdle); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::SetNestableTasksAllowed(bool allowed) { 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (allowed) { 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Kick the native pump just in case we enter a OS-driven nested message 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // loop. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_->ScheduleWork(); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) nestable_tasks_allowed_ = allowed; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::NestableTasksAllowed() const { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return nestable_tasks_allowed_; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::IsNested() { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return run_loop_->run_depth_ > 1; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_observers_.AddObserver(task_observer); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_observers_.RemoveObserver(task_observer); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::is_running() const { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return run_loop_ != NULL; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool MessageLoop::IsHighResolutionTimerEnabledForTesting() { 393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return incoming_task_queue_->IsHighResolutionTimerEnabledForTesting(); 394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool MessageLoop::IsIdleForTesting() { 397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // We only check the imcoming queue|, since we don't want to lock the work 398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // queue. 399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return incoming_task_queue_->IsIdleForTesting(); 400ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 401ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 402ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid MessageLoop::LockWaitUnLockForTesting(WaitableEvent* caller_wait, 403ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch WaitableEvent* caller_signal) { 404ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch incoming_task_queue_->LockWaitUnLockForTesting(caller_wait, caller_signal); 405ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 406ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MessageLoop::Init() { 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!current()) << "should only have one message loop per thread"; 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) lazy_tls_ptr.Pointer()->Set(this); 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) incoming_task_queue_ = new internal::IncomingTaskQueue(this); 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) message_loop_proxy_ = 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new internal::MessageLoopProxyImpl(incoming_task_queue_); 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) thread_task_runner_handle_.reset( 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ThreadTaskRunnerHandle(message_loop_proxy_)); 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Runs the loop in two different SEH modes: 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enable_SEH_restoration_ = false : any unhandled exception goes to the last 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one that calls SetUnhandledExceptionFilter(). 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enable_SEH_restoration_ = true : any unhandled exception goes to the filter 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that was existed before the loop was run. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::RunHandler() { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exception_restoration_) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunInternalInSEHFrame(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunInternal(); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__declspec(noinline) void MessageLoop::RunInternalInSEHFrame() { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LPTOP_LEVEL_EXCEPTION_FILTER current_filter = GetTopSEHFilter(); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __try { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunInternal(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } __except(SEHFilter(current_filter)) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::RunInternal() { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, current()); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartHistogrammer(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if !defined(OS_MACOSX) && !defined(OS_ANDROID) && \ 45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !defined(USE_GTK_MESSAGE_PUMP) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (run_loop_->dispatcher_ && type() == TYPE_UI) { 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<MessagePumpForUI*>(pump_.get())-> 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunWithDispatcher(this, run_loop_->dispatcher_); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_->Run(this); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::ProcessNextDelayedNonNestableTask() { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (run_loop_->run_depth_ != 1) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (deferred_non_nestable_work_queue_.empty()) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingTask pending_task = deferred_non_nestable_work_queue_.front(); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_non_nestable_work_queue_.pop(); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTask(pending_task); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::RunTask(const PendingTask& pending_task) { 4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch tracked_objects::TrackedTime start_time = 4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch tracked_objects::ThreadData::NowForStartOfRun(pending_task.birth_tally); 4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TRACE_EVENT_FLOW_END1("task", "MessageLoop::PostTask", 483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch TRACE_ID_MANGLE(GetTaskTraceID(pending_task)), 4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "queue_duration", 4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (start_time - pending_task.EffectiveTimePosted()).InMilliseconds()); 486424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // When tracing memory for posted tasks it's more valuable to attribute the 487424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // memory allocations to the source function than generically to "RunTask". 488424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) TRACE_EVENT_WITH_MEMORY_TAG2( 489424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "task", "MessageLoop::RunTask", 490424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pending_task.posted_from.function_name(), // Name for memory tracking. 491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "src_file", pending_task.posted_from.file_name(), 492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "src_func", pending_task.posted_from.function_name()); 4937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(nestable_tasks_allowed_); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Execute the task and assume the worst: It is probably not reentrant. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nestable_tasks_allowed_ = false; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Before running the task, store the program counter where it was posted 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and deliberately alias it to ensure it is on the stack if the task 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // crashes. Be careful not to assume that the variable itself will have the 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // expected value when displayed by the optimizer in an optimized build. 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Look at a memory dump of the stack. 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* program_counter = 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_task.posted_from.program_counter(); 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) debug::Alias(&program_counter); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistogramEvent(kTaskRunEvent); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(TaskObserver, task_observers_, 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WillProcessTask(pending_task)); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_task.task.Run(); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(TaskObserver, task_observers_, 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DidProcessTask(pending_task)); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracked_objects::ThreadData::TallyRunOnNamedThreadIfTracking(pending_task, 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time, tracked_objects::ThreadData::NowForEndOfRun()); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nestable_tasks_allowed_ = true; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_task.nestable || run_loop_->run_depth_ == 1) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTask(pending_task); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Show that we ran a task (Note: a new one might arrive as a 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // consequence!). 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We couldn't run the task now because we're in a nested message loop 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and the task isn't nestable. 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_non_nestable_work_queue_.push(pending_task); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::AddToDelayedWorkQueue(const PendingTask& pending_task) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move to the delayed work queue. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_work_queue_.push(pending_task); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::DeletePendingTasks() { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool did_work = !work_queue_.empty(); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!work_queue_.empty()) { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingTask pending_task = work_queue_.front(); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) work_queue_.pop(); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_task.delayed_run_time.is_null()) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to delete delayed tasks in the same order in which they would 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // normally be deleted in case of any funny dependencies between delayed 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tasks. 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddToDelayedWorkQueue(pending_task); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_work |= !deferred_non_nestable_work_queue_.empty(); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!deferred_non_nestable_work_queue_.empty()) { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_non_nestable_work_queue_.pop(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) did_work |= !delayed_work_queue_.empty(); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Historically, we always delete the task regardless of valgrind status. It's 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not completely clear why we want to leak them in the loops above. This 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code is replicating legacy behavior, and should not be considered 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // absolutely "correct" behavior. See TODO above about deleting all tasks 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when it's safe. 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!delayed_work_queue_.empty()) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_work_queue_.pop(); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return did_work; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 569ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochuint64 MessageLoop::GetTaskTraceID(const PendingTask& task) { 570ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return (static_cast<uint64>(task.sequence_num) << 32) | 5713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ((static_cast<uint64>(reinterpret_cast<intptr_t>(this)) << 32) >> 32); 572ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 574ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid MessageLoop::ReloadWorkQueue() { 575ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // We can improve performance of our loading tasks from the incoming queue to 576ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // |*work_queue| by waiting until the last minute (|*work_queue| is empty) to 577ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // load. That reduces the number of locks-per-task significantly when our 578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // queues get large. 579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (work_queue_.empty()) 580ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch incoming_task_queue_->ReloadWorkQueue(&work_queue_); 581ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 583ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid MessageLoop::ScheduleWork(bool was_empty) { 584ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // The Android UI message loop needs to get notified each time 585ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // a task is added to the incoming queue. 586ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (was_empty || AlwaysNotifyPump(type_)) 587ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pump_->ScheduleWork(); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Method and data for histogramming events and actions taken by each instance 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on each thread. 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::StartHistogrammer() { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL) // NaCl build has no metrics code. 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enable_histogrammer_ && !message_histogram_ 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) && StatisticsRecorder::IsActive()) { 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!thread_name_.empty()); 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_histogram_ = LinearHistogram::FactoryGetWithRangeDescription( 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MsgLoop:" + thread_name_, 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLeastNonZeroMessageId, kMaxMessageId, 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kNumberOfDistinctMessagesDisplayed, 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_histogram_->kHexRangePrintingFlag, 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_descriptions_); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::HistogramEvent(int event) { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_histogram_) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_histogram_->Add(event); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::DoWork() { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!nestable_tasks_allowed_) { 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Task can't be executed right now. 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (;;) { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReloadWorkQueue(); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (work_queue_.empty()) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Execute oldest task. 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingTask pending_task = work_queue_.front(); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) work_queue_.pop(); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_task.delayed_run_time.is_null()) { 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddToDelayedWorkQueue(pending_task); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we changed the topmost task, then it is time to reschedule. 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delayed_work_queue_.top().task.Equals(pending_task.task)) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_->ScheduleDelayedWork(pending_task.delayed_run_time); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DeferOrRunPendingTask(pending_task)) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (!work_queue_.empty()); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nothing happened. 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recent_time_ = *next_delayed_work_time = TimeTicks(); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When we "fall behind," there will be a lot of tasks in the delayed work 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // queue that are ready to run. To increase efficiency when we fall behind, 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we will only call Time::Now() intermittently, and then process all tasks 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that are ready to run before calling it again. As a result, the more we 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fall behind (and have a lot of ready-to-run delayed tasks), the more 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // efficient we'll be at handling the tasks. 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_run_time > recent_time_) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recent_time_ = TimeTicks::Now(); // Get a better view of Now(); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_run_time > recent_time_) { 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *next_delayed_work_time = next_run_time; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingTask pending_task = delayed_work_queue_.top(); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_work_queue_.pop(); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delayed_work_queue_.empty()) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DeferOrRunPendingTask(pending_task); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoop::DoIdleWork() { 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ProcessNextDelayedNonNestableTask()) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (run_loop_->quit_when_idle_received_) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_->Quit(); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MessageLoop::GetQueueingInformation(size_t* queue_size, 68958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TimeDelta* queueing_delay) { 69058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *queue_size = work_queue_.size(); 69158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (*queue_size == 0) { 69258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *queueing_delay = TimeDelta(); 69358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 69458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 69558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 69658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const PendingTask& next_to_run = work_queue_.front(); 69758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) tracked_objects::Duration duration = 69858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) tracked_objects::TrackedTime::Now() - next_to_run.EffectiveTimePosted(); 69958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *queueing_delay = TimeDelta::FromMilliseconds(duration.InMilliseconds()); 70058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 70158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::DeleteSoonInternal(const tracked_objects::Location& from_here, 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void(*deleter)(const void*), 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* object) { 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PostNonNestableTask(from_here, Bind(deleter, object)); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoop::ReleaseSoonInternal( 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void(*releaser)(const void*), 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* object) { 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PostNonNestableTask(from_here, Bind(releaser, object)); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageLoopForUI 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoopForUI::Start() { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No Histogram support for UI message loop as it is managed by Java side 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<MessagePumpForUI*>(pump_.get())->Start(this); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoopForUI::Attach() { 727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<MessagePumpUIApplication*>(pump_.get())->Attach(this); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_ANDROID) 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoopForUI::AddObserver(Observer* observer) { 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_ui()->AddObserver(observer); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoopForUI::RemoveObserver(Observer* observer) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_ui()->RemoveObserver(observer); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_ANDROID) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageLoopForIO 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoopForIO::RegisterIOHandler(HANDLE file, IOHandler* handler) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_io()->RegisterIOHandler(file, handler); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoopForIO::RegisterJobObject(HANDLE job, IOHandler* handler) { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pump_io()->RegisterJobObject(job, handler); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoopForIO::WaitForIOCompletion(DWORD timeout, IOHandler* filter) { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pump_io()->WaitForIOCompletion(timeout, filter); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_IOS) 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MessageLoopForIO::WatchFileDescriptor(int fd, 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool persistent, 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mode mode, 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileDescriptorWatcher *controller, 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Watcher *delegate) { 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return pump_io()->WatchFileDescriptor( 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd, 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) persistent, 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mode, 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller, 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate); 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_NACL) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoopForIO::WatchFileDescriptor(int fd, 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool persistent, 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mode mode, 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorWatcher *controller, 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Watcher *delegate) { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pump_libevent()->WatchFileDescriptor( 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd, 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) persistent, 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mode, 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller, 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace base 792