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