message_loop.h revision a02191e04bc25c4935f804f2c080ae28663d096d
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <queue>
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <string>
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/base_export.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/basictypes.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/callback_forward.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/location.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/ref_counted.h"
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/memory/scoped_ptr.h"
17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/incoming_task_queue.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop_proxy_impl.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/observer_list.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/pending_task.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/synchronization/lock.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/tracking_info.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(sky): these includes should not be necessary. Nuke them.
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_win.h"
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_io_ios.h"
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_libevent.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(USE_GLIB) && !defined(OS_NACL)
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/message_loop/message_pump_glib.h"
3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#elif !defined(OS_ANDROID_HOST)
40a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/message_loop/message_pump_glib.h"
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace base {
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HistogramBase;
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class MessagePumpObserver;
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class RunLoop;
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ThreadTaskRunnerHandle;
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_ANDROID)
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class MessagePumpForUI;
5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#elif defined(OS_ANDROID_HOST)
5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)typedef MessagePumpLibevent MessagePumpForUI;
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass WaitableEvent;
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// A MessageLoop is used to process events for a particular thread.  There is
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// at most one MessageLoop instance per thread.
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Events include at a minimum Task instances submitted to PostTask and its
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// variants.  Depending on the type of message pump used by the MessageLoop
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// other events such as UI messages may be processed.  On Windows APC calls (as
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// time permits) and signals sent to a registered set of HANDLEs may also be
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// processed.
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// on the thread where the MessageLoop's Run method executes.
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// NOTE: MessageLoop has task reentrancy protection.  This means that if a
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// task is being processed, a second task cannot start until the first task is
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// finished.  Reentrancy can happen when processing a task, and an inner
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// message pump is created.  That inner pump then processes native messages
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// which could implicitly start an inner task.  Inner message pumps are created
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// (DoDragDrop), printer functions (StartDoc) and *many* others.
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Sample workaround when inner task processing is needed:
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   HRESULT hr;
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   {
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//     MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//     hr = DoDragDrop(...); // Implicitly runs a modal message loop.
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   }
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   // Process |hr| (the result returned by DoDragDrop()).
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Please be SURE your task is reentrant (nestable) and all global variables
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// are stable and accessible before calling SetNestableTasksAllowed(true).
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_WIN)
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpObserver Observer;
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A MessageLoop has a particular type, which indicates the set of
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // asynchronous events it may process in addition to tasks and timers.
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_DEFAULT
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML only supports tasks and timers.
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_UI
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML also supports native UI events (e.g., Windows messages).
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   See also MessageLoopForUI.
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TYPE_GPU
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   This type of ML also supports native UI events for use in the GPU
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   process. On Linux this will always be an X11 ML (as compared with the
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   sometimes-GTK ML in the browser process).
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TYPE_IO
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   This type of ML also supports asynchronous IO.  See also
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   MessageLoopForIO.
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
115bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // TYPE_JAVA
116bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   This type of ML is backed by a Java message handler which is responsible
117bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   for running the tasks added to the ML. This is only for use on Android.
118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   TYPE_JAVA behaves in essence like TYPE_UI, except during construction
119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   where it does not use the main thread specific pump factory.
120bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TYPE_CUSTOM
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //   MessagePump was supplied to constructor.
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Type {
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TYPE_DEFAULT,
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TYPE_UI,
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TYPE_CUSTOM,
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK)
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TYPE_GPU,
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif
131bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    TYPE_IO,
132bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#if defined(OS_ANDROID)
133bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    TYPE_JAVA,
134bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif // defined(OS_ANDROID)
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Normally, it is not necessary to instantiate a MessageLoop.  Instead, it
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // is typical to make use of the current thread's MessageLoop instance.
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  explicit MessageLoop(Type type = TYPE_DEFAULT);
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // be non-NULL.
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit MessageLoop(scoped_ptr<base::MessagePump> pump);
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~MessageLoop();
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoop object for the current thread, or null if none.
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoop* current();
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void EnableHistogrammer(bool enable_histogrammer);
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef scoped_ptr<MessagePump> (MessagePumpFactory)();
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Uses the given base::MessagePumpForUIFactory to override the default
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessagePump implementation for 'TYPE_UI'. Returns true if the factory
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // was successfully registered.
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static bool InitMessagePumpForUIFactory(MessagePumpFactory* factory);
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creates the default MessagePump based on |type|. Caller owns return
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // value.
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static scoped_ptr<MessagePump> CreateMessagePumpForType(Type type);
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A DestructionObserver is notified when the current MessageLoop is being
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // destroyed.  These observers are notified prior to MessageLoop::current()
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // being changed to return NULL.  This gives interested parties the chance to
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // do final cleanup that depends on the MessageLoop.
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: Any tasks posted to the MessageLoop during this notification will
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // not be run.  Instead, they will be deleted.
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class BASE_EXPORT DestructionObserver {
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void WillDestroyCurrentMessageLoop() = 0;
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   protected:
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual ~DestructionObserver();
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Add a DestructionObserver, which will start receiving notifications
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // immediately.
1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddDestructionObserver(DestructionObserver* destruction_observer);
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Remove a DestructionObserver.  It is safe to call this method while a
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // DestructionObserver is receiving a notification callback.
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveDestructionObserver(DestructionObserver* destruction_observer);
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The "PostTask" family of methods call the task's Run method asynchronously
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // from within a message loop at some point in the future.
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // with normal UI or IO event processing.  With the PostDelayedTask variant,
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // tasks are called after at least approximately 'delay_ms' have elapsed.
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The NonNestable variants work similarly except that they promise never to
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // dispatch the task from a nested invocation of MessageLoop::Run.  Instead,
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // such tasks get deferred until the top-most MessageLoop::Run is executing.
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The MessageLoop takes ownership of the Task, and deletes it after it has
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // been Run().
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostTask(from_here, task) is equivalent to
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostDelayedTask(from_here, task, 0).
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: These methods may be called on any thread.  The Task will be invoked
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // on the thread that executes MessageLoop::Run().
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostTask(const tracked_objects::Location& from_here,
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                const Closure& task);
2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostDelayedTask(const tracked_objects::Location& from_here,
2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       const Closure& task,
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       TimeDelta delay);
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostNonNestableTask(const tracked_objects::Location& from_here,
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           const Closure& task);
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  const Closure& task,
2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  TimeDelta delay);
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A variant on PostTask that deletes the given object.  This is useful
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // if the object needs to live until the next run of the MessageLoop (for
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // example, deleting a RenderProcessHost from within an IPC callback is not
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // good).
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: This method may be called on any thread.  The object will be deleted
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // on the thread that executes MessageLoop::Run().  If this is not the same
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // from RefCountedThreadSafe<T>!
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T>
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void DeleteSoon(const tracked_objects::Location& from_here, const T* object) {
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::subtle::DeleteHelperInternal<T, void>::DeleteViaSequencedTaskRunner(
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        this, from_here, object);
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A variant on PostTask that releases the given reference counted object
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // (by calling its Release method).  This is useful if the object needs to
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // live until the next run of the MessageLoop, or if the object needs to be
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // released on a particular thread.
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: This method may be called on any thread.  The object will be
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // released (and thus possibly deleted) on the thread that executes
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessageLoop::Run().  If this is not the same as the thread that calls
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostDelayedTask(FROM_HERE, ), then T MUST inherit from
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // RefCountedThreadSafe<T>!
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T>
2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReleaseSoon(const tracked_objects::Location& from_here,
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   const T* object) {
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner(
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        this, from_here, object);
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Run the message loop.
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Run();
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Process all pending tasks, windows messages, etc., but don't wait/sleep.
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Return as soon as all items that can be run are taken care of.
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunUntilIdle();
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdle().
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Quit() { QuitWhenIdle(); }
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Signals the Run method to return when it becomes idle. It will continue to
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // process pending messages and future messages as long as they are enqueued.
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Warning: if the MessageLoop remains busy, it may never quit. Only use this
2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Quit method when looping procedures (such as web pages) have been shut
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // down.
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // This method may only be called on the same thread that called Run, and Run
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // must still be on the call stack.
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Use QuitClosure variants if you need to Quit another thread's MessageLoop,
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // but note that doing so is fairly dangerous if the target thread makes
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // nested calls to MessageLoop::Run.  The problem being that you won't know
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which nested run loop you are quitting, so be careful!
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void QuitWhenIdle();
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // This method is a variant of Quit, that does not wait for pending messages
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // to be processed before returning from Run.
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void QuitNow();
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure().
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static Closure QuitClosure() { return QuitWhenIdleClosure(); }
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Deprecated: use RunLoop instead.
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // arbitrary MessageLoop to QuitWhenIdle.
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static Closure QuitWhenIdleClosure();
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns true if this loop is |type|. This allows subclasses (especially
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // those in tests) to specialize how they are identified.
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool IsType(Type type) const;
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the type passed to the constructor.
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Type type() const { return type_; }
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Optional call to connect the thread name with this loop.
2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void set_thread_name(const std::string& thread_name) {
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK(thread_name_.empty()) << "Should not rename this thread!";
3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    thread_name_ = thread_name;
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const std::string& thread_name() const { return thread_name_; }
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Gets the message loop proxy associated with this message loop.
3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<MessageLoopProxy> message_loop_proxy() {
307ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return message_loop_proxy_;
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables or disables the recursive task processing. This happens in the case
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // of recursive message loops. Some unwanted message loop may occurs when
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // using common controls or printer functions. By default, recursive task
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // processing is disabled.
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please utilize |ScopedNestableTaskAllower| instead of calling these methods
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // directly.  In general nestable message loops are to be avoided.  They are
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // dangerous and difficult to get right, so please use with extreme caution.
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The specific case where tasks get queued is:
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The thread is running a message loop.
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - It receives a task #1 and execute it.
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The task #1 implicitly start a message loop, like a MessageBox in the
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   unit test. This can also be StartDoc or GetSaveFileName.
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - The thread receives a task #2 before or while in this second message
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   loop.
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // - With NestableTasksAllowed set to true, the task #2 will run right away.
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   Otherwise, it will get executed right after task #1 completes at "thread
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //   message loop level".
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void SetNestableTasksAllowed(bool allowed);
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool NestableTasksAllowed() const;
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Enables nestable tasks on |loop| while in scope.
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class ScopedNestableTaskAllower {
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    explicit ScopedNestableTaskAllower(MessageLoop* loop)
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        : loop_(loop),
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          old_state_(loop_->NestableTasksAllowed()) {
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      loop_->SetNestableTasksAllowed(true);
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ~ScopedNestableTaskAllower() {
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      loop_->SetNestableTasksAllowed(old_state_);
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   private:
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop_;
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool old_state_;
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns true if we are currently running a nested message loop.
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool IsNested();
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A TaskObserver is an object that receives task notifications from the
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessageLoop.
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // NOTE: A TaskObserver implementation should be extremely fast!
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  class BASE_EXPORT TaskObserver {
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   public:
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TaskObserver();
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This method is called before processing a task.
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void WillProcessTask(const PendingTask& pending_task) = 0;
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This method is called after processing a task.
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual void DidProcessTask(const PendingTask& pending_task) = 0;
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)   protected:
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual ~TaskObserver();
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // These functions can only be called on the same thread that |this| is
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // running on.
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddTaskObserver(TaskObserver* task_observer);
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveTaskObserver(TaskObserver* task_observer);
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // When we go into high resolution timer mode, we will stay in hi-res mode
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // for at least 1s.
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void set_os_modal_loop(bool os_modal_loop) {
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    os_modal_loop_ = os_modal_loop;
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool os_modal_loop() const {
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return os_modal_loop_;
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // OS_WIN
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Can only be called from the thread that owns the MessageLoop.
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool is_running() const;
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Returns true if the message loop has high resolution timers enabled.
393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Provided for testing.
394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool IsHighResolutionTimerEnabledForTesting();
395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Returns true if the message loop is "idle". Provided for testing.
397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool IsIdleForTesting();
398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //----------------------------------------------------------------------------
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpWin* pump_win() {
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpWin*>(pump_.get());
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_IOS)
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpLibevent* pump_libevent() {
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpLibevent*>(pump_.get());
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
412ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<MessagePump> pump_;
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
415ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  friend class internal::IncomingTaskQueue;
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend class RunLoop;
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Configures various members for the two constructors.
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Init();
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Invokes the actual run loop using the message pump.
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunHandler();
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Called to process any delayed non-nestable tasks.
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool ProcessNextDelayedNonNestableTask();
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Runs the specified PendingTask.
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunTask(const PendingTask& pending_task);
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Calls RunTask or queues the pending_task on the deferred task list if it
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // cannot be run right now.  Returns true if the task was run.
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool DeferOrRunPendingTask(const PendingTask& pending_task);
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Adds the pending task to delayed_work_queue_.
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddToDelayedWorkQueue(const PendingTask& pending_task);
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Delete tasks that haven't run yet without running them.  Used in the
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // destructor to make sure all the task's destructors get called.  Returns
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // true if some work was done.
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool DeletePendingTasks();
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
442ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Creates a process-wide unique ID to represent this task in trace events.
443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // This will be mangled with a Process ID hash to reduce the likelyhood of
444ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // colliding with MessageLoop pointers on other processes.
445ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  uint64 GetTaskTraceID(const PendingTask& task);
446ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
447ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Loads tasks from the incoming queue to |work_queue_| if the latter is
448ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // empty.
449ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void ReloadWorkQueue();
450ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Wakes up the message pump. Can be called on any thread. The caller is
452ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // responsible for synchronizing ScheduleWork() calls.
453ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void ScheduleWork(bool was_empty);
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Start recording histogram info about events and action IF it was enabled
4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // and IF the statistics recorder can accept a registration of our histogram.
4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void StartHistogrammer();
4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Add occurrence of event to our histogram, so that we can see what is being
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // done in a specific MessageLoop instance (i.e., specific thread).
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If message_histogram_ is NULL, this is a no-op.
4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void HistogramEvent(int event);
4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // MessagePump::Delegate methods:
4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoWork() OVERRIDE;
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) OVERRIDE;
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual bool DoIdleWork() OVERRIDE;
46858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void GetQueueingInformation(size_t* queue_size,
46958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      TimeDelta* queueing_delay) OVERRIDE;
4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const Type type_;
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A list of tasks that need to be processed by this instance.  Note that
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // this queue is only accessed (push/pop) by our current thread.
4757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TaskQueue work_queue_;
4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Contains delayed tasks, sorted by their 'delayed_run_time' property.
4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DelayedTaskQueue delayed_work_queue_;
4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TimeTicks recent_time_;
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A queue of non-nestable tasks that we had to defer because when it came
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // time to execute them we were in a nested message loop.  They will execute
4857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // once we're out of nested message loops.
4867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TaskQueue deferred_non_nestable_work_queue_;
4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<DestructionObserver> destruction_observers_;
4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // A recursion block that prevents accidentally running additional tasks when
4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // insider a (accidentally induced?) nested message pump.
4927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool nestable_tasks_allowed_;
4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which enter a modal message loop.
4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool os_modal_loop_;
4987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
500ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::string thread_name_;
501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // A profiling histogram showing the counts of various messages and events.
502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  HistogramBase* message_histogram_;
503ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
504ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RunLoop* run_loop_;
5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<TaskObserver> task_observers_;
5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
508ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_;
509ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
510ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The message loop proxy associated with this message loop.
511ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_refptr<internal::MessageLoopProxyImpl> message_loop_proxy_;
5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T, class R> friend class base::subtle::DeleteHelperInternal;
5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  template <class T, class R> friend class base::subtle::ReleaseHelperInternal;
5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void DeleteSoonInternal(const tracked_objects::Location& from_here,
5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          void(*deleter)(const void*),
5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          const void* object);
5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReleaseSoonInternal(const tracked_objects::Location& from_here,
5217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           void(*releaser)(const void*),
5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           const void* object);
5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MessageLoop);
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//-----------------------------------------------------------------------------
5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForUI extends MessageLoop with methods that are particular to a
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoop instantiated with TYPE_UI.
5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class is typically used like so:
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   MessageLoopForUI::current()->...call some method...
5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoopForUI : public MessageLoop {
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageLoopForUI() : MessageLoop(TYPE_UI) {
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoopForUI of the current thread.
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoopForUI* current() {
5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK(loop);
5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
5447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessageLoopForUI*>(loop);
5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsCurrent() {
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return loop && loop->type() == MessageLoop::TYPE_UI;
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_IOS)
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // On iOS, the main message loop cannot be Run().  Instead call Attach(),
5547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // which connects this MessageLoop to the UI thread's CFRunLoop and allows
5557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // PostTask() to work.
5567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Attach();
5577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_ANDROID)
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // On Android, the UI message loop is handled by Java side. So Run() should
5617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // never be called. Instead use Start(), which will forward all the native UI
5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // events to the Java message loop.
5637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Start();
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
566a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if !defined(OS_NACL) && defined(OS_WIN)
567a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Please see message_pump_win for definitions of these methods.
5687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddObserver(Observer* observer);
5697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveObserver(Observer* observer);
5707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_OZONE) && !defined(OS_NACL)
573a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Please see MessagePumpLibevent for definition.
574a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  bool WatchFileDescriptor(
575a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      int fd,
576a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      bool persistent,
577a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::Mode mode,
578a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::FileDescriptorWatcher* controller,
579a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      MessagePumpLibevent::Watcher* delegate);
5807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
582a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch protected:
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(rvargas): Make this platform independent.
5857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpForUI* pump_ui() {
5867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpForUI*>(pump_.get());
5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
5897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
5907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Do not add any member variables to MessageLoopForUI!  This is important b/c
5927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForUI is often allocated via MessageLoop(TYPE_UI).  Any extra
5937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// data that you need should be stored on the MessageLoop's pump_ instance.
5947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
5957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MessageLoopForUI_should_not_have_extra_member_variables);
5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//-----------------------------------------------------------------------------
5987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForIO extends MessageLoop with methods that are particular to a
5997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoop instantiated with TYPE_IO.
6007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
6017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class is typically used like so:
6027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//   MessageLoopForIO::current()->...call some method...
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
6047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BASE_EXPORT MessageLoopForIO : public MessageLoop {
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
6077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOHandler IOHandler;
6087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOContext IOContext;
6097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpForIO::IOObserver IOObserver;
6107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
6117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::Watcher Watcher;
6127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::FileDescriptorWatcher
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileDescriptorWatcher;
6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpIOSForIO::IOObserver IOObserver;
6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Mode {
6177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ = MessagePumpIOSForIO::WATCH_READ,
6187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_WRITE = MessagePumpIOSForIO::WATCH_WRITE,
6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ_WRITE = MessagePumpIOSForIO::WATCH_READ_WRITE
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::Watcher Watcher;
6237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::FileDescriptorWatcher
6247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FileDescriptorWatcher;
6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef MessagePumpLibevent::IOObserver IOObserver;
6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  enum Mode {
6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ = MessagePumpLibevent::WATCH_READ,
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_WRITE = MessagePumpLibevent::WATCH_WRITE,
6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    WATCH_READ_WRITE = MessagePumpLibevent::WATCH_READ_WRITE
6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  };
6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessageLoopForIO() : MessageLoop(TYPE_IO) {
6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the MessageLoopForIO of the current thread.
6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static MessageLoopForIO* current() {
6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessageLoopForIO*>(loop);
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsCurrent() {
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MessageLoop* loop = MessageLoop::current();
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return loop && loop->type() == MessageLoop::TYPE_IO;
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddIOObserver(IOObserver* io_observer) {
6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pump_io()->AddIOObserver(io_observer);
6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RemoveIOObserver(IOObserver* io_observer) {
6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pump_io()->RemoveIOObserver(io_observer);
6567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
6597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see MessagePumpWin for definitions of these methods.
6607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RegisterIOHandler(HANDLE file, IOHandler* handler);
6617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool RegisterJobObject(HANDLE job, IOHandler* handler);
6627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
6637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
6657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(rvargas): Make this platform independent.
6667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpForIO* pump_io() {
6677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpForIO*>(pump_.get());
6687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_IOS)
6717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see MessagePumpIOSForIO for definition.
6727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WatchFileDescriptor(int fd,
6737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           bool persistent,
6747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Mode mode,
6757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           FileDescriptorWatcher *controller,
6767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Watcher *delegate);
6777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
6797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpIOSForIO* pump_io() {
6807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpIOSForIO*>(pump_.get());
6817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#elif defined(OS_POSIX)
6847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Please see MessagePumpLibevent for definition.
6857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool WatchFileDescriptor(int fd,
6867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           bool persistent,
6877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Mode mode,
6887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           FileDescriptorWatcher* controller,
6897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           Watcher* delegate);
6907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
6927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MessagePumpLibevent* pump_io() {
6937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return static_cast<MessagePumpLibevent*>(pump_.get());
6947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // defined(OS_POSIX)
6967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
6977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Do not add any member variables to MessageLoopForIO!  This is important b/c
6997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// MessageLoopForIO is often allocated via MessageLoop(TYPE_IO).  Any extra
7007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// data that you need should be stored on the MessageLoop's pump_ instance.
7017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
7027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MessageLoopForIO_should_not_have_extra_member_variables);
7037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace base
7057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif  // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
707