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"
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/debug/task_annotator.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/location.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/ref_counted.h"
17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/memory/scoped_ptr.h"
18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/incoming_task_queue.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop_proxy_impl.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump.h"
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/message_loop/timer_slack.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/observer_list.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/pending_task.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/synchronization/lock.h"
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/tracking_info.h"
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(sky): these includes should not be necessary. Nuke them.
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_win.h"
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_io_ios.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_libevent.h"
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace base {
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HistogramBase;
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.
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // NOTE: Deprecated; prefer task_runner() and the TaskRunner interfaces
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<MessageLoopProxy> message_loop_proxy() {
301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return message_loop_proxy_;
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Gets the TaskRunner associated with this message loop.
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<SingleThreadTaskRunner> task_runner() {
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return message_loop_proxy_;
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables or disables the recursive task processing. This happens in the case
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // of recursive message loops. Some unwanted message loop may occurs when
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // using common controls or printer functions. By default, recursive task
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // processing is disabled.
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please utilize |ScopedNestableTaskAllower| instead of calling these methods
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // directly.  In general nestable message loops are to be avoided.  They are
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // dangerous and difficult to get right, so please use with extreme caution.
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The specific case where tasks get queued is:
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The thread is running a message loop.
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - It receives a task #1 and execute it.
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The task #1 implicitly start a message loop, like a MessageBox in the
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   unit test. This can also be StartDoc or GetSaveFileName.
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The thread receives a task #2 before or while in this second message
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   loop.
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - With NestableTasksAllowed set to true, the task #2 will run right away.
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   Otherwise, it will get executed right after task #1 completes at "thread
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   message loop level".
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void SetNestableTasksAllowed(bool allowed);
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool NestableTasksAllowed() const;
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables nestable tasks on |loop| while in scope.
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class ScopedNestableTaskAllower {
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    explicit ScopedNestableTaskAllower(MessageLoop* loop)
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        : loop_(loop),
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          old_state_(loop_->NestableTasksAllowed()) {
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      loop_->SetNestableTasksAllowed(true);
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ~ScopedNestableTaskAllower() {
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      loop_->SetNestableTasksAllowed(old_state_);
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   private:
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop_;
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool old_state_;
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns true if we are currently running a nested message loop.
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool IsNested();
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A TaskObserver is an object that receives task notifications from the
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessageLoop.
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: A TaskObserver implementation should be extremely fast!
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class BASE_EXPORT TaskObserver {
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TaskObserver();
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This method is called before processing a task.
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void WillProcessTask(const PendingTask& pending_task) = 0;
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This method is called after processing a task.
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void DidProcessTask(const PendingTask& pending_task) = 0;
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   protected:
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual ~TaskObserver();
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // These functions can only be called on the same thread that |this| is
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // running on.
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddTaskObserver(TaskObserver* task_observer);
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveTaskObserver(TaskObserver* task_observer);
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void set_os_modal_loop(bool os_modal_loop) {
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    os_modal_loop_ = os_modal_loop;
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool os_modal_loop() const {
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return os_modal_loop_;
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // OS_WIN
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Can only be called from the thread that owns the MessageLoop.
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool is_running() const;
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Returns true if the message loop has high resolution timers enabled.
388ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Provided for testing.
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool HasHighResolutionTasks();
390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
391ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Returns true if the message loop is "idle". Provided for testing.
392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool IsIdleForTesting();
393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //----------------------------------------------------------------------------
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<MessagePump> pump_;
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  friend class internal::IncomingTaskQueue;
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend class RunLoop;
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Configures various members for the two constructors.
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Init();
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Invokes the actual run loop using the message pump.
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunHandler();
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Called to process any delayed non-nestable tasks.
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool ProcessNextDelayedNonNestableTask();
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Runs the specified PendingTask.
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunTask(const PendingTask& pending_task);
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Calls RunTask or queues the pending_task on the deferred task list if it
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // cannot be run right now.  Returns true if the task was run.
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool DeferOrRunPendingTask(const PendingTask& pending_task);
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Adds the pending task to delayed_work_queue_.
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddToDelayedWorkQueue(const PendingTask& pending_task);
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Delete tasks that haven't run yet without running them.  Used in the
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // destructor to make sure all the task's destructors get called.  Returns
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // true if some work was done.
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool DeletePendingTasks();
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Returns the TaskAnnotator which is used to add debug information to posted
4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // tasks.
4286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  debug::TaskAnnotator* task_annotator() { return &task_annotator_; }
429ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
430ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Loads tasks from the incoming queue to |work_queue_| if the latter is
431ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // empty.
432ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void ReloadWorkQueue();
433ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
434ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Wakes up the message pump. Can be called on any thread. The caller is
435ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // responsible for synchronizing ScheduleWork() calls.
436ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void ScheduleWork(bool was_empty);
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Start recording histogram info about events and action IF it was enabled
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // and IF the statistics recorder can accept a registration of our histogram.
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void StartHistogrammer();
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Add occurrence of event to our histogram, so that we can see what is being
4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // done in a specific MessageLoop instance (i.e., specific thread).
4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If message_histogram_ is NULL, this is a no-op.
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void HistogramEvent(int event);
4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessagePump::Delegate methods:
4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoWork() OVERRIDE;
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) OVERRIDE;
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoIdleWork() 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)
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // How many high resolution tasks are in the pending task queue. This value
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // increases by N every time we call ReloadWorkQueue() and decreases by 1
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // every time we call RunTask() if the task needs a high resolution timer.
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int pending_high_res_tasks_;
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Tracks if we have requested high resolution timers. Its only use is to
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // turn off the high resolution timer upon loop destruction.
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool in_high_res_mode_;
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Contains delayed tasks, sorted by their 'delayed_run_time' property.
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DelayedTaskQueue delayed_work_queue_;
4687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TimeTicks recent_time_;
4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A queue of non-nestable tasks that we had to defer because when it came
4737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // time to execute them we were in a nested message loop.  They will execute
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // once we're out of nested message loops.
4757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TaskQueue deferred_non_nestable_work_queue_;
4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<DestructionObserver> destruction_observers_;
4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A recursion block that prevents accidentally running additional tasks when
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // insider a (accidentally induced?) nested message pump.
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool nestable_tasks_allowed_;
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
4857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which enter a modal message loop.
4867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool os_modal_loop_;
4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
489ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::string thread_name_;
490ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // A profiling histogram showing the counts of various messages and events.
491ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  HistogramBase* message_histogram_;
492ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
493ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RunLoop* run_loop_;
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<TaskObserver> task_observers_;
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  debug::TaskAnnotator task_annotator_;
4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
499ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_;
500ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The message loop proxy associated with this message loop.
502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_refptr<internal::MessageLoopProxyImpl> message_loop_proxy_;
5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T, class R> friend class base::subtle::DeleteHelperInternal;
5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T, class R> friend class base::subtle::ReleaseHelperInternal;
5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void DeleteSoonInternal(const tracked_objects::Location& from_here,
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          void(*deleter)(const void*),
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          const void* object);
5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReleaseSoonInternal(const tracked_objects::Location& from_here,
5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           void(*releaser)(const void*),
5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           const void* object);
5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MessageLoop);
5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if !defined(OS_NACL)
5190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//-----------------------------------------------------------------------------
5217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForUI extends MessageLoop with methods that are particular to a
5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoop instantiated with TYPE_UI.
5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class is typically used like so:
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   MessageLoopForUI::current()->...call some method...
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoopForUI : public MessageLoop {
5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageLoopForUI() : MessageLoop(TYPE_UI) {
5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoopForUI of the current thread.
5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoopForUI* current() {
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK(loop);
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessageLoopForUI*>(loop);
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsCurrent() {
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return loop && loop->type() == MessageLoop::TYPE_UI;
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_IOS)
5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // On iOS, the main message loop cannot be Run().  Instead call Attach(),
5477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which connects this MessageLoop to the UI thread's CFRunLoop and allows
5487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostTask() to work.
5497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Attach();
5507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_ANDROID)
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // On Android, the UI message loop is handled by Java side. So Run() should
5547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // never be called. Instead use Start(), which will forward all the native UI
5557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // events to the Java message loop.
5567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Start();
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
5587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
559116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(USE_OZONE) || (defined(USE_X11) && !defined(USE_GLIB))
560a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Please see MessagePumpLibevent for definition.
561a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  bool WatchFileDescriptor(
562a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      int fd,
563a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      bool persistent,
564a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::Mode mode,
565a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::FileDescriptorWatcher* controller,
566a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::Watcher* delegate);
5677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
5697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Do not add any member variables to MessageLoopForUI!  This is important b/c
5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForUI is often allocated via MessageLoop(TYPE_UI).  Any extra
5727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// data that you need should be stored on the MessageLoop's pump_ instance.
5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MessageLoopForUI_should_not_have_extra_member_variables);
5757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // !defined(OS_NACL)
5770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//-----------------------------------------------------------------------------
5797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForIO extends MessageLoop with methods that are particular to a
5807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoop instantiated with TYPE_IO.
5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class is typically used like so:
5837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   MessageLoopForIO::current()->...call some method...
5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoopForIO : public MessageLoop {
5867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
5870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MessageLoopForIO() : MessageLoop(TYPE_IO) {
5880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Returns the MessageLoopForIO of the current thread.
5910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  static MessageLoopForIO* current() {
5920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MessageLoop* loop = MessageLoop::current();
5930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
5940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return static_cast<MessageLoopForIO*>(loop);
5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  static bool IsCurrent() {
5980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MessageLoop* loop = MessageLoop::current();
5990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return loop && loop->type() == MessageLoop::TYPE_IO;
6000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
6010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if !defined(OS_NACL)
6030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOHandler IOHandler;
6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOContext IOContext;
6077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOObserver IOObserver;
6087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
6097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::Watcher Watcher;
6107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::FileDescriptorWatcher
6117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileDescriptorWatcher;
6127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::IOObserver IOObserver;
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Mode {
6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ = MessagePumpIOSForIO::WATCH_READ,
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_WRITE = MessagePumpIOSForIO::WATCH_WRITE,
6177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ_WRITE = MessagePumpIOSForIO::WATCH_READ_WRITE
6187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::Watcher Watcher;
6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::FileDescriptorWatcher
6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileDescriptorWatcher;
6237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::IOObserver IOObserver;
6247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Mode {
6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ = MessagePumpLibevent::WATCH_READ,
6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_WRITE = MessagePumpLibevent::WATCH_WRITE,
6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ_WRITE = MessagePumpLibevent::WATCH_READ_WRITE
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void AddIOObserver(IOObserver* io_observer);
6330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void RemoveIOObserver(IOObserver* io_observer);
6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see MessagePumpWin for definitions of these methods.
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RegisterIOHandler(HANDLE file, IOHandler* handler);
6387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool RegisterJobObject(HANDLE job, IOHandler* handler);
6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
6400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#elif defined(OS_POSIX)
6410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Please see MessagePumpIOSForIO/MessagePumpLibevent for definition.
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WatchFileDescriptor(int fd,
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           bool persistent,
6447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Mode mode,
6457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           FileDescriptorWatcher *controller,
6467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Watcher *delegate);
6470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // defined(OS_IOS) || defined(OS_POSIX)
6480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // !defined(OS_NACL)
6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Do not add any member variables to MessageLoopForIO!  This is important b/c
6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForIO is often allocated via MessageLoop(TYPE_IO).  Any extra
6537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// data that you need should be stored on the MessageLoop's pump_ instance.
6547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MessageLoopForIO_should_not_have_extra_member_variables);
6567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace base
6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
660