message_loop.h revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <queue>
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <string>
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/base_export.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/basictypes.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/callback_forward.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/location.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/ref_counted.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/observer_list.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/pending_task.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/synchronization/lock.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/tracking_info.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/time.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// We need this to declare base::MessagePumpWin::Dispatcher, which we should
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// really just eliminate.
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_win.h"
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_io_ios.h"
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_libevent.h"
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_NACL)
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_aurax11.h"
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(USE_OZONE) && !defined(OS_NACL)
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_ozone.h"
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#else
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_gtk.h"
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace base {
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HistogramBase;
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class MessageLoopLockTest;
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class RunLoop;
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ThreadTaskRunnerHandle;
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_ANDROID)
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class MessagePumpForUI;
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// A MessageLoop is used to process events for a particular thread.  There is
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// at most one MessageLoop instance per thread.
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Events include at a minimum Task instances submitted to PostTask and its
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// variants.  Depending on the type of message pump used by the MessageLoop
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// other events such as UI messages may be processed.  On Windows APC calls (as
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// time permits) and signals sent to a registered set of HANDLEs may also be
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// processed.
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// on the thread where the MessageLoop's Run method executes.
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// NOTE: MessageLoop has task reentrancy protection.  This means that if a
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// task is being processed, a second task cannot start until the first task is
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// finished.  Reentrancy can happen when processing a task, and an inner
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// message pump is created.  That inner pump then processes native messages
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// which could implicitly start an inner task.  Inner message pumps are created
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// (DoDragDrop), printer functions (StartDoc) and *many* others.
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Sample workaround when inner task processing is needed:
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   HRESULT hr;
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   {
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//     MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//     hr = DoDragDrop(...); // Implicitly runs a modal message loop.
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   }
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   // Process |hr| (the result returned by DoDragDrop()).
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Please be SURE your task is reentrant (nestable) and all global variables
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// are stable and accessible before calling SetNestableTasksAllowed(true).
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpDispatcher Dispatcher;
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpObserver Observer;
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A MessageLoop has a particular type, which indicates the set of
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // asynchronous events it may process in addition to tasks and timers.
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_DEFAULT
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML only supports tasks and timers.
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_UI
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML also supports native UI events (e.g., Windows messages).
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   See also MessageLoopForUI.
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_IO
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML also supports asynchronous IO.  See also
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   MessageLoopForIO.
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Type {
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TYPE_DEFAULT,
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TYPE_UI,
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TYPE_IO
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Normally, it is not necessary to instantiate a MessageLoop.  Instead, it
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // is typical to make use of the current thread's MessageLoop instance.
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  explicit MessageLoop(Type type = TYPE_DEFAULT);
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~MessageLoop();
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoop object for the current thread, or null if none.
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoop* current();
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void EnableHistogrammer(bool enable_histogrammer);
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePump* (MessagePumpFactory)();
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Uses the given base::MessagePumpForUIFactory to override the default
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessagePump implementation for 'TYPE_UI'. Returns true if the factory
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // was successfully registered.
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static bool InitMessagePumpForUIFactory(MessagePumpFactory* factory);
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A DestructionObserver is notified when the current MessageLoop is being
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // destroyed.  These observers are notified prior to MessageLoop::current()
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // being changed to return NULL.  This gives interested parties the chance to
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // do final cleanup that depends on the MessageLoop.
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: Any tasks posted to the MessageLoop during this notification will
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // not be run.  Instead, they will be deleted.
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class BASE_EXPORT DestructionObserver {
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void WillDestroyCurrentMessageLoop() = 0;
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   protected:
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual ~DestructionObserver();
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Add a DestructionObserver, which will start receiving notifications
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // immediately.
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddDestructionObserver(DestructionObserver* destruction_observer);
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Remove a DestructionObserver.  It is safe to call this method while a
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // DestructionObserver is receiving a notification callback.
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveDestructionObserver(DestructionObserver* destruction_observer);
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The "PostTask" family of methods call the task's Run method asynchronously
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // from within a message loop at some point in the future.
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // with normal UI or IO event processing.  With the PostDelayedTask variant,
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // tasks are called after at least approximately 'delay_ms' have elapsed.
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The NonNestable variants work similarly except that they promise never to
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // dispatch the task from a nested invocation of MessageLoop::Run.  Instead,
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // such tasks get deferred until the top-most MessageLoop::Run is executing.
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The MessageLoop takes ownership of the Task, and deletes it after it has
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // been Run().
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostTask(from_here, task) is equivalent to
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostDelayedTask(from_here, task, 0).
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The TryPostTask is meant for the cases where the calling thread cannot
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // block. If posting the task will block, the call returns false, the task
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // is not posted but the task is consumed anyways.
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: These methods may be called on any thread.  The Task will be invoked
1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // on the thread that executes MessageLoop::Run().
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostTask(const tracked_objects::Location& from_here,
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                const Closure& task);
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool TryPostTask(const tracked_objects::Location& from_here,
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   const Closure& task);
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostDelayedTask(const tracked_objects::Location& from_here,
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       const Closure& task,
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       TimeDelta delay);
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostNonNestableTask(const tracked_objects::Location& from_here,
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           const Closure& task);
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  const Closure& task,
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  TimeDelta delay);
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A variant on PostTask that deletes the given object.  This is useful
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // if the object needs to live until the next run of the MessageLoop (for
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // example, deleting a RenderProcessHost from within an IPC callback is not
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // good).
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: This method may be called on any thread.  The object will be deleted
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // on the thread that executes MessageLoop::Run().  If this is not the same
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // from RefCountedThreadSafe<T>!
2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T>
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void DeleteSoon(const tracked_objects::Location& from_here, const T* object) {
2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::subtle::DeleteHelperInternal<T, void>::DeleteViaSequencedTaskRunner(
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        this, from_here, object);
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A variant on PostTask that releases the given reference counted object
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // (by calling its Release method).  This is useful if the object needs to
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // live until the next run of the MessageLoop, or if the object needs to be
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // released on a particular thread.
2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: This method may be called on any thread.  The object will be
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // released (and thus possibly deleted) on the thread that executes
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessageLoop::Run().  If this is not the same as the thread that calls
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostDelayedTask(FROM_HERE, ), then T MUST inherit from
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // RefCountedThreadSafe<T>!
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T>
2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReleaseSoon(const tracked_objects::Location& from_here,
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   const T* object) {
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner(
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        this, from_here, object);
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Run the message loop.
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Run();
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Process all pending tasks, windows messages, etc., but don't wait/sleep.
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Return as soon as all items that can be run are taken care of.
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunUntilIdle();
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdle().
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Quit() { QuitWhenIdle(); }
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Signals the Run method to return when it becomes idle. It will continue to
2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // process pending messages and future messages as long as they are enqueued.
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Warning: if the MessageLoop remains busy, it may never quit. Only use this
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Quit method when looping procedures (such as web pages) have been shut
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // down.
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // This method may only be called on the same thread that called Run, and Run
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // must still be on the call stack.
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Use QuitClosure variants if you need to Quit another thread's MessageLoop,
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // but note that doing so is fairly dangerous if the target thread makes
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // nested calls to MessageLoop::Run.  The problem being that you won't know
2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which nested run loop you are quitting, so be careful!
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void QuitWhenIdle();
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // This method is a variant of Quit, that does not wait for pending messages
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // to be processed before returning from Run.
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void QuitNow();
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure().
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static Closure QuitClosure() { return QuitWhenIdleClosure(); }
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // arbitrary MessageLoop to QuitWhenIdle.
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static Closure QuitWhenIdleClosure();
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns true if this loop is |type|. This allows subclasses (especially
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // those in tests) to specialize how they are identified.
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool IsType(Type type) const;
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the type passed to the constructor.
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Type type() const { return type_; }
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Optional call to connect the thread name with this loop.
2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void set_thread_name(const std::string& thread_name) {
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK(thread_name_.empty()) << "Should not rename this thread!";
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    thread_name_ = thread_name;
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const std::string& thread_name() const { return thread_name_; }
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Gets the message loop proxy associated with this message loop.
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<MessageLoopProxy> message_loop_proxy() {
2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return message_loop_proxy_.get();
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables or disables the recursive task processing. This happens in the case
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // of recursive message loops. Some unwanted message loop may occurs when
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // using common controls or printer functions. By default, recursive task
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // processing is disabled.
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please utilize |ScopedNestableTaskAllower| instead of calling these methods
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // directly.  In general nestable message loops are to be avoided.  They are
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // dangerous and difficult to get right, so please use with extreme caution.
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The specific case where tasks get queued is:
2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The thread is running a message loop.
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - It receives a task #1 and execute it.
3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The task #1 implicitly start a message loop, like a MessageBox in the
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   unit test. This can also be StartDoc or GetSaveFileName.
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The thread receives a task #2 before or while in this second message
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   loop.
3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - With NestableTasksAllowed set to true, the task #2 will run right away.
3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   Otherwise, it will get executed right after task #1 completes at "thread
3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   message loop level".
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void SetNestableTasksAllowed(bool allowed);
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool NestableTasksAllowed() const;
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables nestable tasks on |loop| while in scope.
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class ScopedNestableTaskAllower {
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    explicit ScopedNestableTaskAllower(MessageLoop* loop)
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        : loop_(loop),
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          old_state_(loop_->NestableTasksAllowed()) {
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      loop_->SetNestableTasksAllowed(true);
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ~ScopedNestableTaskAllower() {
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      loop_->SetNestableTasksAllowed(old_state_);
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   private:
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop_;
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool old_state_;
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables or disables the restoration during an exception of the unhandled
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // exception filter that was active when Run() was called. This can happen
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // if some third party code call SetUnhandledExceptionFilter() and never
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // restores the previous filter.
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void set_exception_restoration(bool restore) {
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    exception_restoration_ = restore;
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns true if we are currently running a nested message loop.
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool IsNested();
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A TaskObserver is an object that receives task notifications from the
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessageLoop.
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: A TaskObserver implementation should be extremely fast!
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class BASE_EXPORT TaskObserver {
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TaskObserver();
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This method is called before processing a task.
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void WillProcessTask(const PendingTask& pending_task) = 0;
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This method is called after processing a task.
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void DidProcessTask(const PendingTask& pending_task) = 0;
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   protected:
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual ~TaskObserver();
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // These functions can only be called on the same thread that |this| is
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // running on.
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddTaskObserver(TaskObserver* task_observer);
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveTaskObserver(TaskObserver* task_observer);
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns true if the message loop has high resolution timers enabled.
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Provided for testing.
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool high_resolution_timers_enabled() {
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return !high_resolution_timer_expiration_.is_null();
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#else
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return true;
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // When we go into high resolution timer mode, we will stay in hi-res mode
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // for at least 1s.
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Asserts that the MessageLoop is "idle".
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AssertIdle() const;
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void set_os_modal_loop(bool os_modal_loop) {
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    os_modal_loop_ = os_modal_loop;
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool os_modal_loop() const {
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return os_modal_loop_;
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // OS_WIN
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Can only be called from the thread that owns the MessageLoop.
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool is_running() const;
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //----------------------------------------------------------------------------
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpWin* pump_win() {
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpWin*>(pump_.get());
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_IOS)
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpLibevent* pump_libevent() {
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpLibevent*>(pump_.get());
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<MessagePump> pump_;
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend class RunLoop;
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend class MessageLoopLockTest;
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A function to encapsulate all the exception handling capability in the
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // stacks around the running of a main message loop.  It will run the message
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // loop in a SEH try block or not depending on the set_SEH_restoration()
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // flag invoking respectively RunInternalInSEHFrame() or RunInternal().
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunHandler();
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  __declspec(noinline) void RunInternalInSEHFrame();
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A surrounding stack frame around the running of the message loop that
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // supports all saving and restoring of state, as is needed for any/all (ugly)
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // recursive calls.
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunInternal();
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Called to process any delayed non-nestable tasks.
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool ProcessNextDelayedNonNestableTask();
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Runs the specified PendingTask.
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunTask(const PendingTask& pending_task);
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Calls RunTask or queues the pending_task on the deferred task list if it
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // cannot be run right now.  Returns true if the task was run.
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool DeferOrRunPendingTask(const PendingTask& pending_task);
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Adds the pending task to delayed_work_queue_.
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddToDelayedWorkQueue(const PendingTask& pending_task);
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // This function attempts to add pending task to our incoming_queue_.
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The append can only possibly fail when |use_try_lock| is true.
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // When |use_try_lock| is true, then this call will avoid blocking if
4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the related lock is already held, and will in that case (when the
4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // lock is contended) fail to perform the append, and will return false.
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If the call succeeds to append to the queue, then this call
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // will return true.
4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // In all cases, the caller retains ownership of |pending_task|, but this
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // function will reset the value of pending_task->task.  This is needed to
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // ensure that the posting call stack does not retain pending_task->task
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // beyond this function call.
4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool AddToIncomingQueue(PendingTask* pending_task, bool use_try_lock);
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Load tasks from the incoming_queue_ into work_queue_ if the latter is
4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // empty.  The former requires a lock to access, while the latter is directly
4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // accessible on this thread.
4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReloadWorkQueue();
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Delete tasks that haven't run yet without running them.  Used in the
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // destructor to make sure all the task's destructors get called.  Returns
4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // true if some work was done.
4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool DeletePendingTasks();
4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Calculates the time at which a PendingTask should run.
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TimeTicks CalculateDelayedRuntime(TimeDelta delay);
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Start recording histogram info about events and action IF it was enabled
4697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // and IF the statistics recorder can accept a registration of our histogram.
4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void StartHistogrammer();
4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Add occurrence of event to our histogram, so that we can see what is being
4737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // done in a specific MessageLoop instance (i.e., specific thread).
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If message_histogram_ is NULL, this is a no-op.
4757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void HistogramEvent(int event);
4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessagePump::Delegate methods:
4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoWork() OVERRIDE;
4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) OVERRIDE;
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoIdleWork() OVERRIDE;
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Type type_;
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A list of tasks that need to be processed by this instance.  Note that
4857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // this queue is only accessed (push/pop) by our current thread.
4867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TaskQueue work_queue_;
4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Contains delayed tasks, sorted by their 'delayed_run_time' property.
4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DelayedTaskQueue delayed_work_queue_;
4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
4927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TimeTicks recent_time_;
4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A queue of non-nestable tasks that we had to defer because when it came
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // time to execute them we were in a nested message loop.  They will execute
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // once we're out of nested message loops.
4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TaskQueue deferred_non_nestable_work_queue_;
4987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<DestructionObserver> destruction_observers_;
5007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A recursion block that prevents accidentally running additional tasks when
5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // insider a (accidentally induced?) nested message pump.
5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool nestable_tasks_allowed_;
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool exception_restoration_;
5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string thread_name_;
5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A profiling histogram showing the counts of various messages and events.
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HistogramBase* message_histogram_;
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // An incoming queue of tasks that are acquired under a mutex for processing
5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // on this instance's thread. These tasks have not yet been sorted out into
5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // items for our work_queue_ vs delayed_work_queue_.
5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TaskQueue incoming_queue_;
5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Protect access to incoming_queue_.
5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mutable Lock incoming_queue_lock_;
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  RunLoop* run_loop_;
5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
5217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TimeTicks high_resolution_timer_expiration_;
5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which enter a modal message loop.
5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool os_modal_loop_;
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The next sequence number to use for delayed tasks. Updating this counter is
5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // protected by incoming_queue_lock_.
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int next_sequence_num_;
5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<TaskObserver> task_observers_;
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The message loop proxy associated with this message loop, if one exists.
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<MessageLoopProxy> message_loop_proxy_;
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T, class R> friend class base::subtle::DeleteHelperInternal;
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T, class R> friend class base::subtle::ReleaseHelperInternal;
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void DeleteSoonInternal(const tracked_objects::Location& from_here,
5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          void(*deleter)(const void*),
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          const void* object);
5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReleaseSoonInternal(const tracked_objects::Location& from_here,
5447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           void(*releaser)(const void*),
5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           const void* object);
5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MessageLoop);
5487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
5497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//-----------------------------------------------------------------------------
5517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForUI extends MessageLoop with methods that are particular to a
5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoop instantiated with TYPE_UI.
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class is typically used like so:
5557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   MessageLoopForUI::current()->...call some method...
5567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoopForUI : public MessageLoop {
5587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForUI::MessageFilter MessageFilter;
5617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageLoopForUI() : MessageLoop(TYPE_UI) {
5647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoopForUI of the current thread.
5677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoopForUI* current() {
5687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
5697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK(loop);
5707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessageLoopForUI*>(loop);
5727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
5757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void DidProcessMessage(const MSG& message);
5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // defined(OS_WIN)
5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_IOS)
5797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // On iOS, the main message loop cannot be Run().  Instead call Attach(),
5807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which connects this MessageLoop to the UI thread's CFRunLoop and allows
5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostTask() to work.
5827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Attach();
5837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_ANDROID)
5867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // On Android, the UI message loop is handled by Java side. So Run() should
5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // never be called. Instead use Start(), which will forward all the native UI
5887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // events to the Java message loop.
5897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Start();
5907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif !defined(OS_MACOSX)
5917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see message_pump_win/message_pump_glib for definitions of these
5937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // methods.
5947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddObserver(Observer* observer);
5957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveObserver(Observer* observer);
5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
5987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Plese see MessagePumpForUI for definitions of this method.
5997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void SetMessageFilter(scoped_ptr<MessageFilter> message_filter) {
6007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pump_ui()->SetMessageFilter(message_filter.Pass());
6017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_NACL)
6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend class MessagePumpAuraX11;
6077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
6087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_OZONE) && !defined(OS_NACL)
6097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend class MessagePumpOzone;
6107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
6117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(rvargas): Make this platform independent.
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpForUI* pump_ui() {
6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpForUI*>(pump_.get());
6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // !defined(OS_MACOSX)
6177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
6187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Do not add any member variables to MessageLoopForUI!  This is important b/c
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForUI is often allocated via MessageLoop(TYPE_UI).  Any extra
6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// data that you need should be stored on the MessageLoop's pump_ instance.
6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
6237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MessageLoopForUI_should_not_have_extra_member_variables);
6247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//-----------------------------------------------------------------------------
6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForIO extends MessageLoop with methods that are particular to a
6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoop instantiated with TYPE_IO.
6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class is typically used like so:
6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   MessageLoopForIO::current()->...call some method...
6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoopForIO : public MessageLoop {
6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOHandler IOHandler;
6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOContext IOContext;
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOObserver IOObserver;
6387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::Watcher Watcher;
6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::FileDescriptorWatcher
6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileDescriptorWatcher;
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::IOObserver IOObserver;
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Mode {
6457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ = MessagePumpIOSForIO::WATCH_READ,
6467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_WRITE = MessagePumpIOSForIO::WATCH_WRITE,
6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ_WRITE = MessagePumpIOSForIO::WATCH_READ_WRITE
6487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::Watcher Watcher;
6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::FileDescriptorWatcher
6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileDescriptorWatcher;
6537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::IOObserver IOObserver;
6547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Mode {
6567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ = MessagePumpLibevent::WATCH_READ,
6577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_WRITE = MessagePumpLibevent::WATCH_WRITE,
6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ_WRITE = MessagePumpLibevent::WATCH_READ_WRITE
6597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
6607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
6627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageLoopForIO() : MessageLoop(TYPE_IO) {
6647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoopForIO of the current thread.
6677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoopForIO* current() {
6687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
6697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
6707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessageLoopForIO*>(loop);
6717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddIOObserver(IOObserver* io_observer) {
6747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pump_io()->AddIOObserver(io_observer);
6757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveIOObserver(IOObserver* io_observer) {
6787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pump_io()->RemoveIOObserver(io_observer);
6797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
6827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see MessagePumpWin for definitions of these methods.
6837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RegisterIOHandler(HANDLE file, IOHandler* handler);
6847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool RegisterJobObject(HANDLE job, IOHandler* handler);
6857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
6867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
6887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(rvargas): Make this platform independent.
6897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpForIO* pump_io() {
6907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpForIO*>(pump_.get());
6917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
6947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see MessagePumpIOSForIO for definition.
6957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WatchFileDescriptor(int fd,
6967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           bool persistent,
6977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Mode mode,
6987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           FileDescriptorWatcher *controller,
6997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Watcher *delegate);
7007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
7027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpIOSForIO* pump_io() {
7037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpIOSForIO*>(pump_.get());
7047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
7057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
7077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see MessagePumpLibevent for definition.
7087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WatchFileDescriptor(int fd,
7097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           bool persistent,
7107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Mode mode,
7117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           FileDescriptorWatcher* controller,
7127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Watcher* delegate);
7137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
7157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpLibevent* pump_io() {
7167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpLibevent*>(pump_.get());
7177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
7187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // defined(OS_POSIX)
7197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
7207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Do not add any member variables to MessageLoopForIO!  This is important b/c
7227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForIO is often allocated via MessageLoop(TYPE_IO).  Any extra
7237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// data that you need should be stored on the MessageLoop's pump_ instance.
7247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
7257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MessageLoopForIO_should_not_have_extra_member_variables);
7267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace base
7287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
730