message_loop.h revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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"
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/memory/scoped_ptr.h"
17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/incoming_task_queue.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop_proxy_impl.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/observer_list.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/pending_task.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/synchronization/lock.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/tracking_info.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(sky): these includes should not be necessary. Nuke them.
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_win.h"
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_io_ios.h"
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_libevent.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace base {
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HistogramBase;
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class MessagePumpObserver;
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class RunLoop;
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ThreadTaskRunnerHandle;
43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass WaitableEvent;
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// A MessageLoop is used to process events for a particular thread.  There is
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// at most one MessageLoop instance per thread.
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Events include at a minimum Task instances submitted to PostTask and its
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// variants.  Depending on the type of message pump used by the MessageLoop
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// other events such as UI messages may be processed.  On Windows APC calls (as
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// time permits) and signals sent to a registered set of HANDLEs may also be
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// processed.
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// on the thread where the MessageLoop's Run method executes.
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// NOTE: MessageLoop has task reentrancy protection.  This means that if a
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// task is being processed, a second task cannot start until the first task is
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// finished.  Reentrancy can happen when processing a task, and an inner
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// message pump is created.  That inner pump then processes native messages
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// which could implicitly start an inner task.  Inner message pumps are created
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// (DoDragDrop), printer functions (StartDoc) and *many* others.
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Sample workaround when inner task processing is needed:
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   HRESULT hr;
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   {
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//     MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//     hr = DoDragDrop(...); // Implicitly runs a modal message loop.
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   }
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   // Process |hr| (the result returned by DoDragDrop()).
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Please be SURE your task is reentrant (nestable) and all global variables
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// are stable and accessible before calling SetNestableTasksAllowed(true).
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A MessageLoop has a particular type, which indicates the set of
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // asynchronous events it may process in addition to tasks and timers.
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_DEFAULT
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML only supports tasks and timers.
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_UI
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML also supports native UI events (e.g., Windows messages).
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   See also MessageLoopForUI.
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_IO
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML also supports asynchronous IO.  See also
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   MessageLoopForIO.
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
92bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // TYPE_JAVA
93bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   This type of ML is backed by a Java message handler which is responsible
94bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   for running the tasks added to the ML. This is only for use on Android.
95bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   TYPE_JAVA behaves in essence like TYPE_UI, except during construction
96bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   where it does not use the main thread specific pump factory.
97bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TYPE_CUSTOM
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //   MessagePump was supplied to constructor.
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Type {
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TYPE_DEFAULT,
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TYPE_UI,
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TYPE_CUSTOM,
105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    TYPE_IO,
106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#if defined(OS_ANDROID)
107bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    TYPE_JAVA,
108bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif // defined(OS_ANDROID)
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Normally, it is not necessary to instantiate a MessageLoop.  Instead, it
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // is typical to make use of the current thread's MessageLoop instance.
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  explicit MessageLoop(Type type = TYPE_DEFAULT);
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // be non-NULL.
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit MessageLoop(scoped_ptr<base::MessagePump> pump);
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~MessageLoop();
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoop object for the current thread, or null if none.
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoop* current();
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void EnableHistogrammer(bool enable_histogrammer);
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef scoped_ptr<MessagePump> (MessagePumpFactory)();
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Uses the given base::MessagePumpForUIFactory to override the default
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessagePump implementation for 'TYPE_UI'. Returns true if the factory
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // was successfully registered.
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static bool InitMessagePumpForUIFactory(MessagePumpFactory* factory);
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creates the default MessagePump based on |type|. Caller owns return
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // value.
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static scoped_ptr<MessagePump> CreateMessagePumpForType(Type type);
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A DestructionObserver is notified when the current MessageLoop is being
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // destroyed.  These observers are notified prior to MessageLoop::current()
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // being changed to return NULL.  This gives interested parties the chance to
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // do final cleanup that depends on the MessageLoop.
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: Any tasks posted to the MessageLoop during this notification will
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // not be run.  Instead, they will be deleted.
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class BASE_EXPORT DestructionObserver {
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void WillDestroyCurrentMessageLoop() = 0;
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   protected:
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual ~DestructionObserver();
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Add a DestructionObserver, which will start receiving notifications
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // immediately.
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddDestructionObserver(DestructionObserver* destruction_observer);
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Remove a DestructionObserver.  It is safe to call this method while a
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // DestructionObserver is receiving a notification callback.
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveDestructionObserver(DestructionObserver* destruction_observer);
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The "PostTask" family of methods call the task's Run method asynchronously
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // from within a message loop at some point in the future.
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // with normal UI or IO event processing.  With the PostDelayedTask variant,
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // tasks are called after at least approximately 'delay_ms' have elapsed.
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The NonNestable variants work similarly except that they promise never to
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // dispatch the task from a nested invocation of MessageLoop::Run.  Instead,
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // such tasks get deferred until the top-most MessageLoop::Run is executing.
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The MessageLoop takes ownership of the Task, and deletes it after it has
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // been Run().
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostTask(from_here, task) is equivalent to
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostDelayedTask(from_here, task, 0).
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: These methods may be called on any thread.  The Task will be invoked
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // on the thread that executes MessageLoop::Run().
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostTask(const tracked_objects::Location& from_here,
1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                const Closure& task);
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostDelayedTask(const tracked_objects::Location& from_here,
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       const Closure& task,
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       TimeDelta delay);
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostNonNestableTask(const tracked_objects::Location& from_here,
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           const Closure& task);
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  const Closure& task,
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  TimeDelta delay);
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A variant on PostTask that deletes the given object.  This is useful
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // if the object needs to live until the next run of the MessageLoop (for
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // example, deleting a RenderProcessHost from within an IPC callback is not
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // good).
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: This method may be called on any thread.  The object will be deleted
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // on the thread that executes MessageLoop::Run().  If this is not the same
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // from RefCountedThreadSafe<T>!
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T>
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void DeleteSoon(const tracked_objects::Location& from_here, const T* object) {
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::subtle::DeleteHelperInternal<T, void>::DeleteViaSequencedTaskRunner(
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        this, from_here, object);
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A variant on PostTask that releases the given reference counted object
2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // (by calling its Release method).  This is useful if the object needs to
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // live until the next run of the MessageLoop, or if the object needs to be
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // released on a particular thread.
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // A common pattern is to manually increment the object's reference count
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // (AddRef), clear the pointer, then issue a ReleaseSoon.  The reference count
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // is incremented manually to ensure clearing the pointer does not trigger a
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // delete and to account for the upcoming decrement (ReleaseSoon).  For
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // example:
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  //
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // scoped_refptr<Foo> foo = ...
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // foo->AddRef();
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Foo* raw_foo = foo.get();
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // foo = NULL;
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // message_loop->ReleaseSoon(raw_foo);
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  //
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: This method may be called on any thread.  The object will be
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // released (and thus possibly deleted) on the thread that executes
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessageLoop::Run().  If this is not the same as the thread that calls
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostDelayedTask(FROM_HERE, ), then T MUST inherit from
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // RefCountedThreadSafe<T>!
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T>
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReleaseSoon(const tracked_objects::Location& from_here,
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   const T* object) {
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner(
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        this, from_here, object);
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Run the message loop.
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Run();
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Process all pending tasks, windows messages, etc., but don't wait/sleep.
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Return as soon as all items that can be run are taken care of.
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunUntilIdle();
2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdle().
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Quit() { QuitWhenIdle(); }
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Signals the Run method to return when it becomes idle. It will continue to
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // process pending messages and future messages as long as they are enqueued.
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Warning: if the MessageLoop remains busy, it may never quit. Only use this
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Quit method when looping procedures (such as web pages) have been shut
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // down.
2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // This method may only be called on the same thread that called Run, and Run
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // must still be on the call stack.
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Use QuitClosure variants if you need to Quit another thread's MessageLoop,
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // but note that doing so is fairly dangerous if the target thread makes
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // nested calls to MessageLoop::Run.  The problem being that you won't know
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which nested run loop you are quitting, so be careful!
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void QuitWhenIdle();
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // This method is a variant of Quit, that does not wait for pending messages
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // to be processed before returning from Run.
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void QuitNow();
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure().
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static Closure QuitClosure() { return QuitWhenIdleClosure(); }
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // arbitrary MessageLoop to QuitWhenIdle.
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static Closure QuitWhenIdleClosure();
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns true if this loop is |type|. This allows subclasses (especially
2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // those in tests) to specialize how they are identified.
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool IsType(Type type) const;
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the type passed to the constructor.
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Type type() const { return type_; }
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Optional call to connect the thread name with this loop.
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void set_thread_name(const std::string& thread_name) {
2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK(thread_name_.empty()) << "Should not rename this thread!";
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    thread_name_ = thread_name;
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const std::string& thread_name() const { return thread_name_; }
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Gets the message loop proxy associated with this message loop.
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<MessageLoopProxy> message_loop_proxy() {
293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return message_loop_proxy_;
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables or disables the recursive task processing. This happens in the case
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // of recursive message loops. Some unwanted message loop may occurs when
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // using common controls or printer functions. By default, recursive task
2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // processing is disabled.
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please utilize |ScopedNestableTaskAllower| instead of calling these methods
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // directly.  In general nestable message loops are to be avoided.  They are
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // dangerous and difficult to get right, so please use with extreme caution.
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The specific case where tasks get queued is:
3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The thread is running a message loop.
3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - It receives a task #1 and execute it.
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The task #1 implicitly start a message loop, like a MessageBox in the
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   unit test. This can also be StartDoc or GetSaveFileName.
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The thread receives a task #2 before or while in this second message
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   loop.
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - With NestableTasksAllowed set to true, the task #2 will run right away.
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   Otherwise, it will get executed right after task #1 completes at "thread
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   message loop level".
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void SetNestableTasksAllowed(bool allowed);
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool NestableTasksAllowed() const;
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables nestable tasks on |loop| while in scope.
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class ScopedNestableTaskAllower {
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    explicit ScopedNestableTaskAllower(MessageLoop* loop)
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        : loop_(loop),
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          old_state_(loop_->NestableTasksAllowed()) {
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      loop_->SetNestableTasksAllowed(true);
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ~ScopedNestableTaskAllower() {
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      loop_->SetNestableTasksAllowed(old_state_);
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   private:
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop_;
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool old_state_;
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns true if we are currently running a nested message loop.
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool IsNested();
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A TaskObserver is an object that receives task notifications from the
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessageLoop.
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: A TaskObserver implementation should be extremely fast!
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class BASE_EXPORT TaskObserver {
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TaskObserver();
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This method is called before processing a task.
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void WillProcessTask(const PendingTask& pending_task) = 0;
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This method is called after processing a task.
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void DidProcessTask(const PendingTask& pending_task) = 0;
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   protected:
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual ~TaskObserver();
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // These functions can only be called on the same thread that |this| is
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // running on.
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddTaskObserver(TaskObserver* task_observer);
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveTaskObserver(TaskObserver* task_observer);
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // When we go into high resolution timer mode, we will stay in hi-res mode
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // for at least 1s.
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void set_os_modal_loop(bool os_modal_loop) {
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    os_modal_loop_ = os_modal_loop;
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool os_modal_loop() const {
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return os_modal_loop_;
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // OS_WIN
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Can only be called from the thread that owns the MessageLoop.
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool is_running() const;
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Returns true if the message loop has high resolution timers enabled.
379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Provided for testing.
380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool IsHighResolutionTimerEnabledForTesting();
381ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Returns true if the message loop is "idle". Provided for testing.
383ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool IsIdleForTesting();
384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //----------------------------------------------------------------------------
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<MessagePump> pump_;
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  friend class internal::IncomingTaskQueue;
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend class RunLoop;
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Configures various members for the two constructors.
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Init();
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Invokes the actual run loop using the message pump.
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunHandler();
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Called to process any delayed non-nestable tasks.
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool ProcessNextDelayedNonNestableTask();
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Runs the specified PendingTask.
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunTask(const PendingTask& pending_task);
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Calls RunTask or queues the pending_task on the deferred task list if it
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // cannot be run right now.  Returns true if the task was run.
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool DeferOrRunPendingTask(const PendingTask& pending_task);
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Adds the pending task to delayed_work_queue_.
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddToDelayedWorkQueue(const PendingTask& pending_task);
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Delete tasks that haven't run yet without running them.  Used in the
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // destructor to make sure all the task's destructors get called.  Returns
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // true if some work was done.
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool DeletePendingTasks();
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
417ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Creates a process-wide unique ID to represent this task in trace events.
418ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // This will be mangled with a Process ID hash to reduce the likelyhood of
419ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // colliding with MessageLoop pointers on other processes.
420ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  uint64 GetTaskTraceID(const PendingTask& task);
421ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
422ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Loads tasks from the incoming queue to |work_queue_| if the latter is
423ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // empty.
424ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void ReloadWorkQueue();
425ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
426ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Wakes up the message pump. Can be called on any thread. The caller is
427ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // responsible for synchronizing ScheduleWork() calls.
428ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void ScheduleWork(bool was_empty);
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Start recording histogram info about events and action IF it was enabled
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // and IF the statistics recorder can accept a registration of our histogram.
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void StartHistogrammer();
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Add occurrence of event to our histogram, so that we can see what is being
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // done in a specific MessageLoop instance (i.e., specific thread).
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If message_histogram_ is NULL, this is a no-op.
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void HistogramEvent(int event);
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessagePump::Delegate methods:
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoWork() OVERRIDE;
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) OVERRIDE;
4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoIdleWork() OVERRIDE;
44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void GetQueueingInformation(size_t* queue_size,
44458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      TimeDelta* queueing_delay) OVERRIDE;
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const Type type_;
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A list of tasks that need to be processed by this instance.  Note that
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // this queue is only accessed (push/pop) by our current thread.
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TaskQueue work_queue_;
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Contains delayed tasks, sorted by their 'delayed_run_time' property.
4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DelayedTaskQueue delayed_work_queue_;
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TimeTicks recent_time_;
4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A queue of non-nestable tasks that we had to defer because when it came
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // time to execute them we were in a nested message loop.  They will execute
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // once we're out of nested message loops.
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TaskQueue deferred_non_nestable_work_queue_;
4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<DestructionObserver> destruction_observers_;
4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A recursion block that prevents accidentally running additional tasks when
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // insider a (accidentally induced?) nested message pump.
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool nestable_tasks_allowed_;
4687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which enter a modal message loop.
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool os_modal_loop_;
4737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
475ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::string thread_name_;
476ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // A profiling histogram showing the counts of various messages and events.
477ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  HistogramBase* message_histogram_;
478ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
479ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RunLoop* run_loop_;
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<TaskObserver> task_observers_;
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_;
484ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The message loop proxy associated with this message loop.
486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_refptr<internal::MessageLoopProxyImpl> message_loop_proxy_;
4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T, class R> friend class base::subtle::DeleteHelperInternal;
4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T, class R> friend class base::subtle::ReleaseHelperInternal;
4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void DeleteSoonInternal(const tracked_objects::Location& from_here,
4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          void(*deleter)(const void*),
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          const void* object);
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReleaseSoonInternal(const tracked_objects::Location& from_here,
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           void(*releaser)(const void*),
4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           const void* object);
4987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MessageLoop);
5007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if !defined(OS_NACL)
5030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//-----------------------------------------------------------------------------
5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForUI extends MessageLoop with methods that are particular to a
5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoop instantiated with TYPE_UI.
5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class is typically used like so:
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   MessageLoopForUI::current()->...call some method...
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoopForUI : public MessageLoop {
5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageLoopForUI() : MessageLoop(TYPE_UI) {
5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoopForUI of the current thread.
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoopForUI* current() {
5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK(loop);
5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
5217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessageLoopForUI*>(loop);
5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsCurrent() {
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return loop && loop->type() == MessageLoop::TYPE_UI;
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_IOS)
5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // On iOS, the main message loop cannot be Run().  Instead call Attach(),
5317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which connects this MessageLoop to the UI thread's CFRunLoop and allows
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostTask() to work.
5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Attach();
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_ANDROID)
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // On Android, the UI message loop is handled by Java side. So Run() should
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // never be called. Instead use Start(), which will forward all the native UI
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // events to the Java message loop.
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Start();
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(OS_WIN)
5440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  typedef MessagePumpObserver Observer;
5450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
546a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Please see message_pump_win for definitions of these methods.
5477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddObserver(Observer* observer);
5487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveObserver(Observer* observer);
5497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(USE_OZONE) || (defined(OS_CHROMEOS) && !defined(USE_GLIB))
552a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Please see MessagePumpLibevent for definition.
553a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  bool WatchFileDescriptor(
554a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      int fd,
555a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      bool persistent,
556a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::Mode mode,
557a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::FileDescriptorWatcher* controller,
558a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::Watcher* delegate);
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
5617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Do not add any member variables to MessageLoopForUI!  This is important b/c
5637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForUI is often allocated via MessageLoop(TYPE_UI).  Any extra
5647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// data that you need should be stored on the MessageLoop's pump_ instance.
5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
5667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MessageLoopForUI_should_not_have_extra_member_variables);
5677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // !defined(OS_NACL)
5690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//-----------------------------------------------------------------------------
5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForIO extends MessageLoop with methods that are particular to a
5727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoop instantiated with TYPE_IO.
5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class is typically used like so:
5757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   MessageLoopForIO::current()->...call some method...
5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoopForIO : public MessageLoop {
5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
5790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MessageLoopForIO() : MessageLoop(TYPE_IO) {
5800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Returns the MessageLoopForIO of the current thread.
5830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  static MessageLoopForIO* current() {
5840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MessageLoop* loop = MessageLoop::current();
5850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
5860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return static_cast<MessageLoopForIO*>(loop);
5870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  static bool IsCurrent() {
5900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MessageLoop* loop = MessageLoop::current();
5910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return loop && loop->type() == MessageLoop::TYPE_IO;
5920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if !defined(OS_NACL)
5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOHandler IOHandler;
5987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOContext IOContext;
5997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOObserver IOObserver;
6007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
6017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::Watcher Watcher;
6027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::FileDescriptorWatcher
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileDescriptorWatcher;
6047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::IOObserver IOObserver;
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Mode {
6077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ = MessagePumpIOSForIO::WATCH_READ,
6087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_WRITE = MessagePumpIOSForIO::WATCH_WRITE,
6097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ_WRITE = MessagePumpIOSForIO::WATCH_READ_WRITE
6107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
6117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
6127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::Watcher Watcher;
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::FileDescriptorWatcher
6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileDescriptorWatcher;
6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::IOObserver IOObserver;
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Mode {
6187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ = MessagePumpLibevent::WATCH_READ,
6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_WRITE = MessagePumpLibevent::WATCH_WRITE,
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ_WRITE = MessagePumpLibevent::WATCH_READ_WRITE
6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
6237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void AddIOObserver(IOObserver* io_observer);
6250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void RemoveIOObserver(IOObserver* io_observer);
6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see MessagePumpWin for definitions of these methods.
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RegisterIOHandler(HANDLE file, IOHandler* handler);
6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool RegisterJobObject(HANDLE job, IOHandler* handler);
6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
6320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#elif defined(OS_POSIX)
6330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Please see MessagePumpIOSForIO/MessagePumpLibevent for definition.
6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WatchFileDescriptor(int fd,
6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           bool persistent,
6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Mode mode,
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           FileDescriptorWatcher *controller,
6387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Watcher *delegate);
6390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // defined(OS_IOS) || defined(OS_POSIX)
6400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // !defined(OS_NACL)
6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Do not add any member variables to MessageLoopForIO!  This is important b/c
6447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForIO is often allocated via MessageLoop(TYPE_IO).  Any extra
6457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// data that you need should be stored on the MessageLoop's pump_ instance.
6467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MessageLoopForIO_should_not_have_extra_member_variables);
6487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace base
6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
652