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