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