13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_MESSAGE_LOOP_H_
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_MESSAGE_LOOP_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <queue>
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump.h"
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/observer_list.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/lock.h"
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/task.h"
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We need this to declare base::MessagePumpWin::Dispatcher, which we should
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// really just eliminate.
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump_win.h"
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX)
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump_libevent.h"
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_MACOSX)
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_pump_glib.h"
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsentypedef struct _XDisplay Display;
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
31513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(TOUCH_UI)
32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/message_pump_glib_x_dispatch.h"
33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
35731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace base {
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass Histogram;
37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A MessageLoop is used to process events for a particular thread.  There is
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// at most one MessageLoop instance per thread.
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Events include at a minimum Task instances submitted to PostTask or those
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// managed by TimerManager.  Depending on the type of message pump used by the
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoop other events such as UI messages may be processed.  On Windows
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// APC calls (as time permits) and signals sent to a registered set of HANDLEs
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// may also be processed.
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// on the thread where the MessageLoop's Run method executes.
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NOTE: MessageLoop has task reentrancy protection.  This means that if a
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// task is being processed, a second task cannot start until the first task is
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// finished.  Reentrancy can happen when processing a task, and an inner
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// message pump is created.  That inner pump then processes native messages
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// which could implicitly start an inner task.  Inner message pumps are created
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (DoDragDrop), printer functions (StartDoc) and *many* others.
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Sample workaround when inner task processing is needed:
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   bool old_state = MessageLoop::current()->NestableTasksAllowed();
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   MessageLoop::current()->SetNestableTasksAllowed(true);
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   HRESULT hr = DoDragDrop(...); // Implicitly runs a modal message loop here.
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   MessageLoop::current()->SetNestableTasksAllowed(old_state);
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   // Process hr  (the result returned by DoDragDrop().
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Please be SURE your task is reentrant (nestable) and all global variables
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// are stable and accessible before calling SetNestableTasksAllowed(true).
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API MessageLoop : public base::MessagePump::Delegate {
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(OS_WIN)
723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  typedef base::MessagePumpWin::Dispatcher Dispatcher;
733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  typedef base::MessagePumpForUI::Observer Observer;
743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#elif !defined(OS_MACOSX)
753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(TOUCH_UI)
763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  typedef base::MessagePumpGlibXDispatcher Dispatcher;
773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#else
783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  typedef base::MessagePumpForUI::Dispatcher Dispatcher;
793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif
803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  typedef base::MessagePumpForUI::Observer Observer;
813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // A MessageLoop has a particular type, which indicates the set of
843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // asynchronous events it may process in addition to tasks and timers.
853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //
863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // TYPE_DEFAULT
873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //   This type of ML only supports tasks and timers.
883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //
893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // TYPE_UI
903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //   This type of ML also supports native UI events (e.g., Windows messages).
913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //   See also MessageLoopForUI.
923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //
933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // TYPE_IO
943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //   This type of ML also supports asynchronous IO.  See also
953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //   MessageLoopForIO.
963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //
973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  enum Type {
983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    TYPE_DEFAULT,
993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    TYPE_UI,
1003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    TYPE_IO
1013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  };
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Normally, it is not necessary to instantiate a MessageLoop.  Instead, it
1043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // is typical to make use of the current thread's MessageLoop instance.
1053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  explicit MessageLoop(Type type = TYPE_DEFAULT);
1063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ~MessageLoop();
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Returns the MessageLoop object for the current thread, or null if none.
1093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static MessageLoop* current();
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void EnableHistogrammer(bool enable_histogrammer);
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A DestructionObserver is notified when the current MessageLoop is being
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // destroyed.  These obsevers are notified prior to MessageLoop::current()
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // being changed to return NULL.  This gives interested parties the chance to
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // do final cleanup that depends on the MessageLoop.
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // NOTE: Any tasks posted to the MessageLoop during this notification will
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // not be run.  Instead, they will be deleted.
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  class BASE_API DestructionObserver {
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   public:
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    virtual void WillDestroyCurrentMessageLoop() = 0;
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick   protected:
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual ~DestructionObserver();
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Add a DestructionObserver, which will start receiving notifications
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // immediately.
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void AddDestructionObserver(DestructionObserver* destruction_observer);
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Remove a DestructionObserver.  It is safe to call this method while a
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // DestructionObserver is receiving a notification callback.
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RemoveDestructionObserver(DestructionObserver* destruction_observer);
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The "PostTask" family of methods call the task's Run method asynchronously
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // from within a message loop at some point in the future.
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // with normal UI or IO event processing.  With the PostDelayedTask variant,
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // tasks are called after at least approximately 'delay_ms' have elapsed.
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The NonNestable variants work similarly except that they promise never to
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // dispatch the task from a nested invocation of MessageLoop::Run.  Instead,
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // such tasks get deferred until the top-most MessageLoop::Run is executing.
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The MessageLoop takes ownership of the Task, and deletes it after it has
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // been Run().
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // NOTE: These methods may be called on any thread.  The Task will be invoked
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // on the thread that executes MessageLoop::Run().
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void PostTask(
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const tracked_objects::Location& from_here, Task* task);
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void PostDelayedTask(
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const tracked_objects::Location& from_here, Task* task, int64 delay_ms);
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void PostNonNestableTask(
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const tracked_objects::Location& from_here, Task* task);
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void PostNonNestableDelayedTask(
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const tracked_objects::Location& from_here, Task* task, int64 delay_ms);
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A variant on PostTask that deletes the given object.  This is useful
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // if the object needs to live until the next run of the MessageLoop (for
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // example, deleting a RenderProcessHost from within an IPC callback is not
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // good).
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // NOTE: This method may be called on any thread.  The object will be deleted
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // on the thread that executes MessageLoop::Run().  If this is not the same
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // from RefCountedThreadSafe<T>!
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class T>
176513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void DeleteSoon(const tracked_objects::Location& from_here, const T* object) {
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    PostNonNestableTask(from_here, new DeleteTask<T>(object));
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A variant on PostTask that releases the given reference counted object
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (by calling its Release method).  This is useful if the object needs to
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // live until the next run of the MessageLoop, or if the object needs to be
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // released on a particular thread.
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // NOTE: This method may be called on any thread.  The object will be
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // released (and thus possibly deleted) on the thread that executes
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // MessageLoop::Run().  If this is not the same as the thread that calls
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // PostDelayedTask(FROM_HERE, ), then T MUST inherit from
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // RefCountedThreadSafe<T>!
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class T>
191513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void ReleaseSoon(const tracked_objects::Location& from_here,
192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                   const T* object) {
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    PostNonNestableTask(from_here, new ReleaseTask<T>(object));
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Run the message loop.
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Run();
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Process all pending tasks, windows messages, etc., but don't wait/sleep.
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Return as soon as all items that can be run are taken care of.
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RunAllPending();
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Signals the Run method to return after it is done processing all pending
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // messages.  This method may only be called on the same thread that called
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Run, and Run must still be on the call stack.
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Use QuitTask if you need to Quit another thread's MessageLoop, but note
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // that doing so is fairly dangerous if the target thread makes nested calls
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to MessageLoop::Run.  The problem being that you won't know which nested
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // run loop you are quiting, so be careful!
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Quit();
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This method is a variant of Quit, that does not wait for pending messages
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to be processed before returning from Run.
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void QuitNow();
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Invokes Quit on the current MessageLoop when run.  Useful to schedule an
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // arbitrary MessageLoop to Quit.
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  class QuitTask : public Task {
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   public:
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    virtual void Run() {
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      MessageLoop::current()->Quit();
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the type passed to the constructor.
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Type type() const { return type_; }
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Optional call to connect the thread name with this loop.
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_thread_name(const std::string& thread_name) {
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(thread_name_.empty()) << "Should not rename this thread!";
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    thread_name_ = thread_name;
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const std::string& thread_name() const { return thread_name_; }
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Enables or disables the recursive task processing. This happens in the case
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // of recursive message loops. Some unwanted message loop may occurs when
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // using common controls or printer functions. By default, recursive task
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // processing is disabled.
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The specific case where tasks get queued is:
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // - The thread is running a message loop.
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // - It receives a task #1 and execute it.
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // - The task #1 implicitly start a message loop, like a MessageBox in the
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //   unit test. This can also be StartDoc or GetSaveFileName.
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // - The thread receives a task #2 before or while in this second message
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //   loop.
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // - With NestableTasksAllowed set to true, the task #2 will run right away.
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //   Otherwise, it will get executed right after task #1 completes at "thread
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //   message loop level".
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void SetNestableTasksAllowed(bool allowed);
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool NestableTasksAllowed() const;
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Enables nestable tasks on |loop| while in scope.
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  class ScopedNestableTaskAllower {
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   public:
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    explicit ScopedNestableTaskAllower(MessageLoop* loop)
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        : loop_(loop),
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          old_state_(loop_->NestableTasksAllowed()) {
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      loop_->SetNestableTasksAllowed(true);
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ~ScopedNestableTaskAllower() {
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      loop_->SetNestableTasksAllowed(old_state_);
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   private:
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MessageLoop* loop_;
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bool old_state_;
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Enables or disables the restoration during an exception of the unhandled
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // exception filter that was active when Run() was called. This can happen
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // if some third party code call SetUnhandledExceptionFilter() and never
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // restores the previous filter.
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_exception_restoration(bool restore) {
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    exception_restoration_ = restore;
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns true if we are currently running a nested message loop.
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool IsNested();
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // A TaskObserver is an object that receives task notifications from the
2843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // MessageLoop.
2853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //
2863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // NOTE: A TaskObserver implementation should be extremely fast!
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  class BASE_API TaskObserver {
2883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen   public:
2893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    TaskObserver();
2903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // This method is called before processing a task.
2923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    virtual void WillProcessTask(const Task* task) = 0;
2933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // This method is called after processing a task.
2953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    virtual void DidProcessTask(const Task* task) = 0;
2963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen   protected:
2983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    virtual ~TaskObserver();
2993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  };
3003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These functions can only be called on the same thread that |this| is
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // running on.
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddTaskObserver(TaskObserver* task_observer);
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void RemoveTaskObserver(TaskObserver* task_observer);
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true if the message loop has high resolution timers enabled.
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Provided for testing.
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool high_resolution_timers_enabled() {
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return !high_resolution_timer_expiration_.is_null();
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When we go into high resolution timer mode, we will stay in hi-res mode
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for at least 1s.
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Asserts that the MessageLoop is "idle".
32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void AssertIdle() const;
32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_WIN)
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void set_os_modal_loop(bool os_modal_loop) {
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    os_modal_loop_ = os_modal_loop;
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool os_modal_loop() const {
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return os_modal_loop_;
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif  // OS_WIN
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //----------------------------------------------------------------------------
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  struct RunState {
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Used to count how many Run() invocations are on the stack.
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int run_depth;
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Used to record that Quit() was called, or that we should quit the pump
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // once it becomes idle.
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bool quit_received;
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_MACOSX)
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Dispatcher* dispatcher;
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  class AutoRunState : RunState {
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   public:
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    explicit AutoRunState(MessageLoop* loop);
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ~AutoRunState();
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   private:
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MessageLoop* loop_;
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RunState* previous_state_;
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This structure is copied around by value.
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  struct PendingTask {
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    PendingTask(Task* task, bool nestable)
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        : task(task), sequence_num(0), nestable(nestable) {
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Used to support sorting.
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bool operator<(const PendingTask& other) const;
3653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    Task* task;                        // The task to run.
3673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    base::TimeTicks delayed_run_time;  // The time when the task should be run.
3683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    int sequence_num;                  // Secondary sort key for run time.
3693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    bool nestable;                     // OK to dispatch from a nested loop.
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  class TaskQueue : public std::queue<PendingTask> {
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   public:
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    void Swap(TaskQueue* queue) {
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      c.swap(queue->c);  // Calls std::deque::swap
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  typedef std::priority_queue<PendingTask> DelayedTaskQueue;
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::MessagePumpWin* pump_win() {
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<base::MessagePumpWin*>(pump_.get());
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX)
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::MessagePumpLibevent* pump_libevent() {
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<base::MessagePumpLibevent*>(pump_.get());
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A function to encapsulate all the exception handling capability in the
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // stacks around the running of a main message loop.  It will run the message
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // loop in a SEH try block or not depending on the set_SEH_restoration()
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // flag invoking respectively RunInternalInSEHFrame() or RunInternal().
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RunHandler();
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  __declspec(noinline) void RunInternalInSEHFrame();
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A surrounding stack frame around the running of the message loop that
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // supports all saving and restoring of state, as is needed for any/all (ugly)
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // recursive calls.
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RunInternal();
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Called to process any delayed non-nestable tasks.
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ProcessNextDelayedNonNestableTask();
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Runs the specified task and deletes it.
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RunTask(Task* task);
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Calls RunTask or queues the pending_task on the deferred task list if it
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // cannot be run right now.  Returns true if the task was run.
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool DeferOrRunPendingTask(const PendingTask& pending_task);
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Adds the pending task to delayed_work_queue_.
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void AddToDelayedWorkQueue(const PendingTask& pending_task);
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Load tasks from the incoming_queue_ into work_queue_ if the latter is
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // empty.  The former requires a lock to access, while the latter is directly
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // accessible on this thread.
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ReloadWorkQueue();
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Delete tasks that haven't run yet without running them.  Used in the
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // destructor to make sure all the task's destructors get called.  Returns
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // true if some work was done.
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool DeletePendingTasks();
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Post a task to our incomming queue.
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void PostTask_Helper(const tracked_objects::Location& from_here, Task* task,
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       int64 delay_ms, bool nestable);
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start recording histogram info about events and action IF it was enabled
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and IF the statistics recorder can accept a registration of our histogram.
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void StartHistogrammer();
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Add occurence of event to our histogram, so that we can see what is being
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // done in a specific MessageLoop instance (i.e., specific thread).
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If message_histogram_ is NULL, this is a no-op.
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void HistogramEvent(int event);
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // base::MessagePump::Delegate methods:
4433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual bool DoWork();
4443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time);
4453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual bool DoIdleWork();
4463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Type type_;
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A list of tasks that need to be processed by this instance.  Note that
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // this queue is only accessed (push/pop) by our current thread.
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TaskQueue work_queue_;
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Contains delayed tasks, sorted by their 'delayed_run_time' property.
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DelayedTaskQueue delayed_work_queue_;
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
456513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
457513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  base::TimeTicks recent_time_;
458513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A queue of non-nestable tasks that we had to defer because when it came
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // time to execute them we were in a nested message loop.  They will execute
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // once we're out of nested message loops.
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TaskQueue deferred_non_nestable_work_queue_;
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<base::MessagePump> pump_;
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ObserverList<DestructionObserver> destruction_observers_;
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A recursion block that prevents accidentally running additonal tasks when
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // insider a (accidentally induced?) nested message pump.
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool nestable_tasks_allowed_;
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool exception_restoration_;
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string thread_name_;
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A profiling histogram showing the counts of various messages and events.
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::Histogram* message_histogram_;
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A null terminated list which creates an incoming_queue of tasks that are
479dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // acquired under a mutex for processing on this instance's thread. These
480dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // tasks have not yet been sorted out into items for our work_queue_ vs
481dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // items that will be handled by the TimerManager.
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TaskQueue incoming_queue_;
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Protect access to incoming_queue_.
48472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  mutable base::Lock incoming_queue_lock_;
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunState* state_;
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeTicks high_resolution_timer_expiration_;
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // which enter a modal message loop.
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool os_modal_loop_;
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The next sequence number to use for delayed tasks.
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int next_sequence_num_;
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ObserverList<TaskObserver> task_observers_;
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(MessageLoop);
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//-----------------------------------------------------------------------------
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoopForUI extends MessageLoop with methods that are particular to a
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoop instantiated with TYPE_UI.
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class is typically used like so:
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   MessageLoopForUI::current()->...call some method...
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API MessageLoopForUI : public MessageLoop {
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoopForUI() : MessageLoop(TYPE_UI) {
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the MessageLoopForUI of the current thread.
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static MessageLoopForUI* current() {
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MessageLoop* loop = MessageLoop::current();
5199639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen#ifdef ANDROID
5209639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen    DCHECK_EQ(static_cast<int>(MessageLoop::TYPE_UI),
5219639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen              static_cast<int>(loop->type()));
5229639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen#else
52358d02015f8788a79b322c58d4bdbc914e4c333dcKristian Monsen    DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
5249639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen#endif
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<MessageLoopForUI*>(loop);
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void DidProcessMessage(const MSG& message);
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // defined(OS_WIN)
531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
532dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(USE_X11)
533dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Returns the Xlib Display that backs the MessagePump for this MessageLoop.
534dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  //
535dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // This allows for raw access to the X11 server in situations where our
536dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // abstractions do not provide enough power.
537dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  //
538dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Be careful how this is used. The MessagePump in general expects
539dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // exclusive access to the Display. Calling things like XNextEvent() will
540dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // likely break things in subtle, hard to detect, ways.
541dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  Display* GetDisplay();
542dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif  // defined(OS_X11)
543dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !defined(OS_MACOSX)
545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Please see message_pump_win/message_pump_glib for definitions of these
546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // methods.
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void AddObserver(Observer* observer);
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RemoveObserver(Observer* observer);
549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Run(Dispatcher* dispatcher);
550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // TODO(rvargas): Make this platform independent.
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::MessagePumpForUI* pump_ui() {
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<base::MessagePumpForUI*>(pump_.get());
555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // !defined(OS_MACOSX)
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Do not add any member variables to MessageLoopForUI!  This is important b/c
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoopForUI is often allocated via MessageLoop(TYPE_UI).  Any extra
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// data that you need should be stored on the MessageLoop's pump_ instance.
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCOMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott               MessageLoopForUI_should_not_have_extra_member_variables);
564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//-----------------------------------------------------------------------------
566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoopForIO extends MessageLoop with methods that are particular to a
567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoop instantiated with TYPE_IO.
568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class is typically used like so:
570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   MessageLoopForIO::current()->...call some method...
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API MessageLoopForIO : public MessageLoop {
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::MessagePumpForIO::IOHandler IOHandler;
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::MessagePumpForIO::IOContext IOContext;
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::MessagePumpForIO::IOObserver IOObserver;
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::MessagePumpLibevent::Watcher Watcher;
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::MessagePumpLibevent::FileDescriptorWatcher
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      FileDescriptorWatcher;
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef base::MessagePumpLibevent::IOObserver IOObserver;
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum Mode {
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WATCH_READ = base::MessagePumpLibevent::WATCH_READ,
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WATCH_WRITE = base::MessagePumpLibevent::WATCH_WRITE,
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WATCH_READ_WRITE = base::MessagePumpLibevent::WATCH_READ_WRITE
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoopForIO() : MessageLoop(TYPE_IO) {
593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the MessageLoopForIO of the current thread.
596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static MessageLoopForIO* current() {
597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MessageLoop* loop = MessageLoop::current();
5989639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen#ifdef ANDROID
5999639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen    DCHECK_EQ(static_cast<int>(MessageLoop::TYPE_IO),
6009639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen              static_cast<int>(loop->type()));
6019639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen#else
60258d02015f8788a79b322c58d4bdbc914e4c333dcKristian Monsen    DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
6039639f9bb6f038fcff8d26463ba0ac698357eee46Kristian Monsen#endif
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<MessageLoopForIO*>(loop);
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddIOObserver(IOObserver* io_observer) {
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pump_io()->AddIOObserver(io_observer);
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void RemoveIOObserver(IOObserver* io_observer) {
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pump_io()->RemoveIOObserver(io_observer);
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Please see MessagePumpWin for definitions of these methods.
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void RegisterIOHandler(HANDLE file_handle, IOHandler* handler);
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // TODO(rvargas): Make this platform independent.
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::MessagePumpForIO* pump_io() {
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<base::MessagePumpForIO*>(pump_.get());
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX)
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Please see MessagePumpLibevent for definition.
628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WatchFileDescriptor(int fd,
629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                           bool persistent,
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                           Mode mode,
631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                           FileDescriptorWatcher *controller,
632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                           Watcher *delegate);
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::MessagePumpLibevent* pump_io() {
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return static_cast<base::MessagePumpLibevent*>(pump_.get());
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // defined(OS_POSIX)
639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Do not add any member variables to MessageLoopForIO!  This is important b/c
642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MessageLoopForIO is often allocated via MessageLoop(TYPE_IO).  Any extra
643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// data that you need should be stored on the MessageLoop's pump_ instance.
644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCOMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott               MessageLoopForIO_should_not_have_extra_member_variables);
646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // BASE_MESSAGE_LOOP_H_
648