blob: 9355ec957b0d856fb344202ec20401f5a0b3ecfb [file] [log] [blame]
[email protected]a502bbe72011-01-07 18:06:451// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]fc7fb6e2008-08-16 03:09:055#ifndef BASE_MESSAGE_LOOP_H_
6#define BASE_MESSAGE_LOOP_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
initial.commitd7cae122008-07-26 21:49:388
initial.commitd7cae122008-07-26 21:49:389#include <queue>
10#include <string>
initial.commitd7cae122008-07-26 21:49:3811
[email protected]0bea7252011-08-05 15:34:0012#include "base/base_export.h"
[email protected]9cfb89a2010-06-09 21:20:4113#include "base/basictypes.h"
[email protected]b224f792011-04-20 16:02:2314#include "base/callback.h"
[email protected]3b63f8f42011-03-28 01:54:1515#include "base/memory/ref_counted.h"
[email protected]fc7fb6e2008-08-16 03:09:0516#include "base/message_pump.h"
initial.commitd7cae122008-07-26 21:49:3817#include "base/observer_list.h"
[email protected]20305ec2011-01-21 04:55:5218#include "base/synchronization/lock.h"
initial.commitd7cae122008-07-26 21:49:3819#include "base/task.h"
[email protected]b224f792011-04-20 16:02:2320#include "base/time.h"
21#include "base/tracked.h"
initial.commitd7cae122008-07-26 21:49:3822
[email protected]fc7fb6e2008-08-16 03:09:0523#if defined(OS_WIN)
24// We need this to declare base::MessagePumpWin::Dispatcher, which we should
25// really just eliminate.
26#include "base/message_pump_win.h"
[email protected]36987e92008-09-18 18:46:2627#elif defined(OS_POSIX)
28#include "base/message_pump_libevent.h"
[email protected]e43eddf12009-12-29 00:32:5229#if !defined(OS_MACOSX)
[email protected]4076d2f2011-08-11 18:20:2230
31#if defined(USE_WAYLAND)
32#include "base/message_pump_wayland.h"
33#elif defined(TOUCH_UI)
[email protected]2047ef42011-06-24 20:10:2534#include "base/message_pump_x.h"
35#else
36#include "base/message_pump_gtk.h"
37#endif
[email protected]4076d2f2011-08-11 18:20:2238
[email protected]faabcf42009-05-18 21:12:3439#endif
[email protected]e43eddf12009-12-29 00:32:5240#endif
[email protected]ea15e982008-08-15 07:31:2041
[email protected]835d7c82010-10-14 04:38:3842namespace base {
[email protected]5097dc82010-07-15 17:23:2343class Histogram;
[email protected]835d7c82010-10-14 04:38:3844}
[email protected]5097dc82010-07-15 17:23:2345
[email protected]b224f792011-04-20 16:02:2346#if defined(TRACK_ALL_TASK_OBJECTS)
47namespace tracked_objects {
48class Births;
49}
50#endif // defined(TRACK_ALL_TASK_OBJECTS)
51
[email protected]fc7fb6e2008-08-16 03:09:0552// A MessageLoop is used to process events for a particular thread. There is
53// at most one MessageLoop instance per thread.
54//
55// Events include at a minimum Task instances submitted to PostTask or those
56// managed by TimerManager. Depending on the type of message pump used by the
57// MessageLoop other events such as UI messages may be processed. On Windows
58// APC calls (as time permits) and signals sent to a registered set of HANDLEs
59// may also be processed.
initial.commitd7cae122008-07-26 21:49:3860//
61// NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
62// on the thread where the MessageLoop's Run method executes.
63//
[email protected]fc7fb6e2008-08-16 03:09:0564// NOTE: MessageLoop has task reentrancy protection. This means that if a
initial.commitd7cae122008-07-26 21:49:3865// task is being processed, a second task cannot start until the first task is
[email protected]fc7fb6e2008-08-16 03:09:0566// finished. Reentrancy can happen when processing a task, and an inner
67// message pump is created. That inner pump then processes native messages
68// which could implicitly start an inner task. Inner message pumps are created
69// with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions
70// (DoDragDrop), printer functions (StartDoc) and *many* others.
71//
initial.commitd7cae122008-07-26 21:49:3872// Sample workaround when inner task processing is needed:
73// bool old_state = MessageLoop::current()->NestableTasksAllowed();
74// MessageLoop::current()->SetNestableTasksAllowed(true);
75// HRESULT hr = DoDragDrop(...); // Implicitly runs a modal message loop here.
76// MessageLoop::current()->SetNestableTasksAllowed(old_state);
77// // Process hr (the result returned by DoDragDrop().
78//
[email protected]fc7fb6e2008-08-16 03:09:0579// Please be SURE your task is reentrant (nestable) and all global variables
80// are stable and accessible before calling SetNestableTasksAllowed(true).
initial.commitd7cae122008-07-26 21:49:3881//
[email protected]0bea7252011-08-05 15:34:0082class BASE_EXPORT MessageLoop : public base::MessagePump::Delegate {
initial.commitd7cae122008-07-26 21:49:3883 public:
[email protected]a502bbe72011-01-07 18:06:4584#if defined(OS_WIN)
85 typedef base::MessagePumpWin::Dispatcher Dispatcher;
86 typedef base::MessagePumpForUI::Observer Observer;
[email protected]5040dfab2011-05-11 20:50:0087#elif !defined(OS_MACOSX)
[email protected]2047ef42011-06-24 20:10:2588 typedef base::MessagePumpDispatcher Dispatcher;
89 typedef base::MessagePumpObserver Observer;
[email protected]a502bbe72011-01-07 18:06:4590#endif
91
92 // A MessageLoop has a particular type, which indicates the set of
93 // asynchronous events it may process in addition to tasks and timers.
[email protected]9cfb89a2010-06-09 21:20:4194 //
[email protected]a502bbe72011-01-07 18:06:4595 // TYPE_DEFAULT
96 // This type of ML only supports tasks and timers.
97 //
98 // TYPE_UI
99 // This type of ML also supports native UI events (e.g., Windows messages).
100 // See also MessageLoopForUI.
101 //
102 // TYPE_IO
103 // This type of ML also supports asynchronous IO. See also
104 // MessageLoopForIO.
105 //
106 enum Type {
107 TYPE_DEFAULT,
108 TYPE_UI,
109 TYPE_IO
[email protected]9cfb89a2010-06-09 21:20:41110 };
111
[email protected]a502bbe72011-01-07 18:06:45112 // Normally, it is not necessary to instantiate a MessageLoop. Instead, it
113 // is typical to make use of the current thread's MessageLoop instance.
114 explicit MessageLoop(Type type = TYPE_DEFAULT);
[email protected]3690ebe02011-05-25 09:08:19115 virtual ~MessageLoop();
[email protected]a502bbe72011-01-07 18:06:45116
[email protected]9989c9bb2011-01-07 20:23:43117 // Returns the MessageLoop object for the current thread, or null if none.
118 static MessageLoop* current();
119
initial.commitd7cae122008-07-26 21:49:38120 static void EnableHistogrammer(bool enable_histogrammer);
121
[email protected]61c86c62011-08-02 16:11:16122 typedef base::MessagePump* (MessagePumpFactory)();
123 // Using the given base::MessagePumpForUIFactory to override the default
124 // MessagePump implementation for 'TYPE_UI'.
125 static void InitMessagePumpForUIFactory(MessagePumpFactory* factory);
126
[email protected]ee132ad2008-08-06 21:27:02127 // A DestructionObserver is notified when the current MessageLoop is being
128 // destroyed. These obsevers are notified prior to MessageLoop::current()
129 // being changed to return NULL. This gives interested parties the chance to
130 // do final cleanup that depends on the MessageLoop.
131 //
132 // NOTE: Any tasks posted to the MessageLoop during this notification will
133 // not be run. Instead, they will be deleted.
134 //
[email protected]0bea7252011-08-05 15:34:00135 class BASE_EXPORT DestructionObserver {
[email protected]ee132ad2008-08-06 21:27:02136 public:
[email protected]ee132ad2008-08-06 21:27:02137 virtual void WillDestroyCurrentMessageLoop() = 0;
[email protected]23c386b2010-09-15 22:14:36138
139 protected:
140 virtual ~DestructionObserver();
[email protected]ee132ad2008-08-06 21:27:02141 };
142
143 // Add a DestructionObserver, which will start receiving notifications
144 // immediately.
145 void AddDestructionObserver(DestructionObserver* destruction_observer);
146
147 // Remove a DestructionObserver. It is safe to call this method while a
148 // DestructionObserver is receiving a notification callback.
149 void RemoveDestructionObserver(DestructionObserver* destruction_observer);
150
[email protected]752578562008-09-07 08:08:29151 // The "PostTask" family of methods call the task's Run method asynchronously
152 // from within a message loop at some point in the future.
initial.commitd7cae122008-07-26 21:49:38153 //
[email protected]752578562008-09-07 08:08:29154 // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed
155 // with normal UI or IO event processing. With the PostDelayedTask variant,
156 // tasks are called after at least approximately 'delay_ms' have elapsed.
initial.commitd7cae122008-07-26 21:49:38157 //
[email protected]752578562008-09-07 08:08:29158 // The NonNestable variants work similarly except that they promise never to
159 // dispatch the task from a nested invocation of MessageLoop::Run. Instead,
160 // such tasks get deferred until the top-most MessageLoop::Run is executing.
161 //
162 // The MessageLoop takes ownership of the Task, and deletes it after it has
163 // been Run().
164 //
165 // NOTE: These methods may be called on any thread. The Task will be invoked
initial.commitd7cae122008-07-26 21:49:38166 // on the thread that executes MessageLoop::Run().
[email protected]b0992172008-10-27 18:54:18167
[email protected]752578562008-09-07 08:08:29168 void PostTask(
169 const tracked_objects::Location& from_here, Task* task);
[email protected]b0992172008-10-27 18:54:18170
[email protected]752578562008-09-07 08:08:29171 void PostDelayedTask(
[email protected]743ace42009-06-17 17:23:51172 const tracked_objects::Location& from_here, Task* task, int64 delay_ms);
initial.commitd7cae122008-07-26 21:49:38173
[email protected]752578562008-09-07 08:08:29174 void PostNonNestableTask(
175 const tracked_objects::Location& from_here, Task* task);
initial.commitd7cae122008-07-26 21:49:38176
[email protected]752578562008-09-07 08:08:29177 void PostNonNestableDelayedTask(
[email protected]743ace42009-06-17 17:23:51178 const tracked_objects::Location& from_here, Task* task, int64 delay_ms);
initial.commitd7cae122008-07-26 21:49:38179
[email protected]b224f792011-04-20 16:02:23180 // TODO(ajwong): Remove the functions above once the Task -> Closure migration
181 // is complete.
182 //
183 // There are 2 sets of Post*Task functions, one which takes the older Task*
184 // function object representation, and one that takes the newer base::Closure.
185 // We have this overload to allow a staged transition between the two systems.
186 // Once the transition is done, the functions above should be deleted.
187 void PostTask(
188 const tracked_objects::Location& from_here,
189 const base::Closure& task);
190
191 void PostDelayedTask(
192 const tracked_objects::Location& from_here,
193 const base::Closure& task, int64 delay_ms);
194
195 void PostNonNestableTask(
196 const tracked_objects::Location& from_here,
197 const base::Closure& task);
198
199 void PostNonNestableDelayedTask(
200 const tracked_objects::Location& from_here,
201 const base::Closure& task, int64 delay_ms);
202
initial.commitd7cae122008-07-26 21:49:38203 // A variant on PostTask that deletes the given object. This is useful
204 // if the object needs to live until the next run of the MessageLoop (for
205 // example, deleting a RenderProcessHost from within an IPC callback is not
206 // good).
207 //
208 // NOTE: This method may be called on any thread. The object will be deleted
209 // on the thread that executes MessageLoop::Run(). If this is not the same
210 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit
211 // from RefCountedThreadSafe<T>!
212 template <class T>
[email protected]00ed48f2010-10-22 22:19:24213 void DeleteSoon(const tracked_objects::Location& from_here, const T* object) {
[email protected]752578562008-09-07 08:08:29214 PostNonNestableTask(from_here, new DeleteTask<T>(object));
initial.commitd7cae122008-07-26 21:49:38215 }
216
217 // A variant on PostTask that releases the given reference counted object
218 // (by calling its Release method). This is useful if the object needs to
219 // live until the next run of the MessageLoop, or if the object needs to be
220 // released on a particular thread.
221 //
222 // NOTE: This method may be called on any thread. The object will be
223 // released (and thus possibly deleted) on the thread that executes
224 // MessageLoop::Run(). If this is not the same as the thread that calls
225 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from
226 // RefCountedThreadSafe<T>!
227 template <class T>
[email protected]00ed48f2010-10-22 22:19:24228 void ReleaseSoon(const tracked_objects::Location& from_here,
229 const T* object) {
[email protected]752578562008-09-07 08:08:29230 PostNonNestableTask(from_here, new ReleaseTask<T>(object));
initial.commitd7cae122008-07-26 21:49:38231 }
232
[email protected]3882c4332008-07-30 19:03:59233 // Run the message loop.
initial.commitd7cae122008-07-26 21:49:38234 void Run();
235
[email protected]7e0e8762008-07-31 13:10:20236 // Process all pending tasks, windows messages, etc., but don't wait/sleep.
237 // Return as soon as all items that can be run are taken care of.
238 void RunAllPending();
[email protected]3882c4332008-07-30 19:03:59239
initial.commitd7cae122008-07-26 21:49:38240 // Signals the Run method to return after it is done processing all pending
[email protected]fc7fb6e2008-08-16 03:09:05241 // messages. This method may only be called on the same thread that called
242 // Run, and Run must still be on the call stack.
initial.commitd7cae122008-07-26 21:49:38243 //
[email protected]fc7fb6e2008-08-16 03:09:05244 // Use QuitTask if you need to Quit another thread's MessageLoop, but note
245 // that doing so is fairly dangerous if the target thread makes nested calls
246 // to MessageLoop::Run. The problem being that you won't know which nested
247 // run loop you are quiting, so be careful!
248 //
initial.commitd7cae122008-07-26 21:49:38249 void Quit();
250
[email protected]781a7ed2010-02-23 07:12:22251 // This method is a variant of Quit, that does not wait for pending messages
252 // to be processed before returning from Run.
253 void QuitNow();
254
[email protected]fc7fb6e2008-08-16 03:09:05255 // Invokes Quit on the current MessageLoop when run. Useful to schedule an
initial.commitd7cae122008-07-26 21:49:38256 // arbitrary MessageLoop to Quit.
257 class QuitTask : public Task {
258 public:
259 virtual void Run() {
260 MessageLoop::current()->Quit();
261 }
262 };
263
[email protected]4d9bdfaf2008-08-26 05:53:57264 // Returns the type passed to the constructor.
265 Type type() const { return type_; }
266
initial.commitd7cae122008-07-26 21:49:38267 // Optional call to connect the thread name with this loop.
[email protected]fc7fb6e2008-08-16 03:09:05268 void set_thread_name(const std::string& thread_name) {
269 DCHECK(thread_name_.empty()) << "Should not rename this thread!";
270 thread_name_ = thread_name;
271 }
[email protected]ee132ad2008-08-06 21:27:02272 const std::string& thread_name() const { return thread_name_; }
initial.commitd7cae122008-07-26 21:49:38273
initial.commitd7cae122008-07-26 21:49:38274 // Enables or disables the recursive task processing. This happens in the case
275 // of recursive message loops. Some unwanted message loop may occurs when
276 // using common controls or printer functions. By default, recursive task
277 // processing is disabled.
278 //
279 // The specific case where tasks get queued is:
280 // - The thread is running a message loop.
281 // - It receives a task #1 and execute it.
282 // - The task #1 implicitly start a message loop, like a MessageBox in the
283 // unit test. This can also be StartDoc or GetSaveFileName.
284 // - The thread receives a task #2 before or while in this second message
285 // loop.
286 // - With NestableTasksAllowed set to true, the task #2 will run right away.
287 // Otherwise, it will get executed right after task #1 completes at "thread
288 // message loop level".
289 void SetNestableTasksAllowed(bool allowed);
290 bool NestableTasksAllowed() const;
291
[email protected]18d6a8f2009-12-16 22:56:33292 // Enables nestable tasks on |loop| while in scope.
293 class ScopedNestableTaskAllower {
294 public:
295 explicit ScopedNestableTaskAllower(MessageLoop* loop)
296 : loop_(loop),
297 old_state_(loop_->NestableTasksAllowed()) {
298 loop_->SetNestableTasksAllowed(true);
299 }
300 ~ScopedNestableTaskAllower() {
301 loop_->SetNestableTasksAllowed(old_state_);
302 }
303
304 private:
305 MessageLoop* loop_;
306 bool old_state_;
307 };
308
initial.commitd7cae122008-07-26 21:49:38309 // Enables or disables the restoration during an exception of the unhandled
310 // exception filter that was active when Run() was called. This can happen
311 // if some third party code call SetUnhandledExceptionFilter() and never
312 // restores the previous filter.
313 void set_exception_restoration(bool restore) {
314 exception_restoration_ = restore;
315 }
316
[email protected]b5f95102009-07-01 19:53:59317 // Returns true if we are currently running a nested message loop.
318 bool IsNested();
319
[email protected]a502bbe72011-01-07 18:06:45320 // A TaskObserver is an object that receives task notifications from the
321 // MessageLoop.
322 //
323 // NOTE: A TaskObserver implementation should be extremely fast!
[email protected]0bea7252011-08-05 15:34:00324 class BASE_EXPORT TaskObserver {
[email protected]a502bbe72011-01-07 18:06:45325 public:
326 TaskObserver();
327
328 // This method is called before processing a task.
[email protected]b224f792011-04-20 16:02:23329 virtual void WillProcessTask(base::TimeTicks time_posted) = 0;
[email protected]a502bbe72011-01-07 18:06:45330
331 // This method is called after processing a task.
[email protected]b224f792011-04-20 16:02:23332 virtual void DidProcessTask(base::TimeTicks time_posted) = 0;
[email protected]a502bbe72011-01-07 18:06:45333
334 protected:
335 virtual ~TaskObserver();
336 };
337
[email protected]9cfb89a2010-06-09 21:20:41338 // These functions can only be called on the same thread that |this| is
339 // running on.
340 void AddTaskObserver(TaskObserver* task_observer);
341 void RemoveTaskObserver(TaskObserver* task_observer);
342
[email protected]57f030a2010-06-29 04:58:15343 // Returns true if the message loop has high resolution timers enabled.
344 // Provided for testing.
345 bool high_resolution_timers_enabled() {
346#if defined(OS_WIN)
347 return !high_resolution_timer_expiration_.is_null();
348#else
349 return true;
350#endif
351 }
352
353 // When we go into high resolution timer mode, we will stay in hi-res mode
354 // for at least 1s.
355 static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
356
[email protected]8d6ab8f52011-01-26 00:53:48357 // Asserts that the MessageLoop is "idle".
358 void AssertIdle() const;
359
[email protected]2ec01fe2011-03-24 03:40:28360#if defined(OS_WIN)
361 void set_os_modal_loop(bool os_modal_loop) {
362 os_modal_loop_ = os_modal_loop;
363 }
364
365 bool os_modal_loop() const {
366 return os_modal_loop_;
367 }
368#endif // OS_WIN
369
initial.commitd7cae122008-07-26 21:49:38370 //----------------------------------------------------------------------------
[email protected]4d9bdfaf2008-08-26 05:53:57371 protected:
[email protected]fc7fb6e2008-08-16 03:09:05372 struct RunState {
373 // Used to count how many Run() invocations are on the stack.
374 int run_depth;
initial.commitd7cae122008-07-26 21:49:38375
[email protected]fc7fb6e2008-08-16 03:09:05376 // Used to record that Quit() was called, or that we should quit the pump
377 // once it becomes idle.
378 bool quit_received;
initial.commitd7cae122008-07-26 21:49:38379
[email protected]61c86c62011-08-02 16:11:16380#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]148d1052009-07-31 22:53:37381 Dispatcher* dispatcher;
[email protected]fc7fb6e2008-08-16 03:09:05382#endif
383 };
384
[email protected]61c86c62011-08-02 16:11:16385#if defined(OS_ANDROID)
386 // Android Java process manages the UI thread message loop. So its
387 // MessagePumpForUI needs to keep the RunState.
388 public:
389#endif
[email protected]0bea7252011-08-05 15:34:00390 class BASE_EXPORT AutoRunState : RunState {
[email protected]fc7fb6e2008-08-16 03:09:05391 public:
[email protected]b0992172008-10-27 18:54:18392 explicit AutoRunState(MessageLoop* loop);
[email protected]fc7fb6e2008-08-16 03:09:05393 ~AutoRunState();
initial.commitd7cae122008-07-26 21:49:38394 private:
395 MessageLoop* loop_;
[email protected]fc7fb6e2008-08-16 03:09:05396 RunState* previous_state_;
397 };
[email protected]61c86c62011-08-02 16:11:16398#if defined(OS_ANDROID)
399 protected:
400#endif
initial.commitd7cae122008-07-26 21:49:38401
[email protected]752578562008-09-07 08:08:29402 // This structure is copied around by value.
403 struct PendingTask {
[email protected]b224f792011-04-20 16:02:23404 PendingTask(const base::Closure& task,
405 const tracked_objects::Location& posted_from,
406 base::TimeTicks delayed_run_time,
407 bool nestable);
408 ~PendingTask();
[email protected]b0992172008-10-27 18:54:18409
[email protected]752578562008-09-07 08:08:29410 // Used to support sorting.
411 bool operator<(const PendingTask& other) const;
[email protected]a502bbe72011-01-07 18:06:45412
[email protected]b224f792011-04-20 16:02:23413 // The task to run.
414 base::Closure task;
415
416#if defined(TRACK_ALL_TASK_OBJECTS)
417 // Counter for location where the Closure was posted from.
418 tracked_objects::Births* post_births;
419#endif // defined(TRACK_ALL_TASK_OBJECTS)
420
421 // Time this PendingTask was posted.
422 base::TimeTicks time_posted;
423
424 // The time when the task should be run.
425 base::TimeTicks delayed_run_time;
426
427 // Secondary sort key for run time.
428 int sequence_num;
429
430 // OK to dispatch from a nested loop.
431 bool nestable;
[email protected]fcb30f7b2011-05-19 22:28:25432
433 // The site this PendingTask was posted from.
434 const void* birth_program_counter;
initial.commitd7cae122008-07-26 21:49:38435 };
436
[email protected]b2f0ea12009-09-02 20:05:21437 class TaskQueue : public std::queue<PendingTask> {
438 public:
439 void Swap(TaskQueue* queue) {
440 c.swap(queue->c); // Calls std::deque::swap
441 }
442 };
443
[email protected]4bed5d82008-12-17 03:50:05444 typedef std::priority_queue<PendingTask> DelayedTaskQueue;
initial.commitd7cae122008-07-26 21:49:38445
[email protected]fc7fb6e2008-08-16 03:09:05446#if defined(OS_WIN)
447 base::MessagePumpWin* pump_win() {
448 return static_cast<base::MessagePumpWin*>(pump_.get());
449 }
[email protected]36987e92008-09-18 18:46:26450#elif defined(OS_POSIX)
451 base::MessagePumpLibevent* pump_libevent() {
452 return static_cast<base::MessagePumpLibevent*>(pump_.get());
453 }
[email protected]fc7fb6e2008-08-16 03:09:05454#endif
[email protected]3882c4332008-07-30 19:03:59455
456 // A function to encapsulate all the exception handling capability in the
[email protected]fc7fb6e2008-08-16 03:09:05457 // stacks around the running of a main message loop. It will run the message
458 // loop in a SEH try block or not depending on the set_SEH_restoration()
[email protected]aff8a132009-10-26 18:15:59459 // flag invoking respectively RunInternalInSEHFrame() or RunInternal().
[email protected]fc7fb6e2008-08-16 03:09:05460 void RunHandler();
initial.commitd7cae122008-07-26 21:49:38461
[email protected]aff8a132009-10-26 18:15:59462#if defined(OS_WIN)
463 __declspec(noinline) void RunInternalInSEHFrame();
464#endif
465
[email protected]3882c4332008-07-30 19:03:59466 // A surrounding stack frame around the running of the message loop that
467 // supports all saving and restoring of state, as is needed for any/all (ugly)
468 // recursive calls.
[email protected]fc7fb6e2008-08-16 03:09:05469 void RunInternal();
[email protected]ea15e982008-08-15 07:31:20470
[email protected]fc7fb6e2008-08-16 03:09:05471 // Called to process any delayed non-nestable tasks.
initial.commitd7cae122008-07-26 21:49:38472 bool ProcessNextDelayedNonNestableTask();
initial.commitd7cae122008-07-26 21:49:38473
[email protected]b224f792011-04-20 16:02:23474 // Runs the specified PendingTask.
475 void RunTask(const PendingTask& pending_task);
initial.commitd7cae122008-07-26 21:49:38476
[email protected]752578562008-09-07 08:08:29477 // Calls RunTask or queues the pending_task on the deferred task list if it
478 // cannot be run right now. Returns true if the task was run.
479 bool DeferOrRunPendingTask(const PendingTask& pending_task);
initial.commitd7cae122008-07-26 21:49:38480
[email protected]001747c2008-09-10 00:37:07481 // Adds the pending task to delayed_work_queue_.
482 void AddToDelayedWorkQueue(const PendingTask& pending_task);
483
[email protected]b224f792011-04-20 16:02:23484 // Adds the pending task to our incoming_queue_.
485 //
486 // Caller retains ownership of |pending_task|, but this function will
487 // reset the value of pending_task->task. This is needed to ensure
488 // that the posting call stack does not retain pending_task->task
489 // beyond this function call.
490 void AddToIncomingQueue(PendingTask* pending_task);
491
initial.commitd7cae122008-07-26 21:49:38492 // Load tasks from the incoming_queue_ into work_queue_ if the latter is
493 // empty. The former requires a lock to access, while the latter is directly
494 // accessible on this thread.
495 void ReloadWorkQueue();
496
497 // Delete tasks that haven't run yet without running them. Used in the
[email protected]001747c2008-09-10 00:37:07498 // destructor to make sure all the task's destructors get called. Returns
499 // true if some work was done.
500 bool DeletePendingTasks();
initial.commitd7cae122008-07-26 21:49:38501
[email protected]b224f792011-04-20 16:02:23502 // Calcuates the time at which a PendingTask should run.
503 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms);
[email protected]fc7fb6e2008-08-16 03:09:05504
initial.commitd7cae122008-07-26 21:49:38505 // Start recording histogram info about events and action IF it was enabled
506 // and IF the statistics recorder can accept a registration of our histogram.
507 void StartHistogrammer();
508
509 // Add occurence of event to our histogram, so that we can see what is being
510 // done in a specific MessageLoop instance (i.e., specific thread).
511 // If message_histogram_ is NULL, this is a no-op.
512 void HistogramEvent(int event);
513
[email protected]a502bbe72011-01-07 18:06:45514 // base::MessagePump::Delegate methods:
515 virtual bool DoWork();
516 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time);
517 virtual bool DoIdleWork();
518
[email protected]4d9bdfaf2008-08-26 05:53:57519 Type type_;
520
[email protected]752578562008-09-07 08:08:29521 // A list of tasks that need to be processed by this instance. Note that
522 // this queue is only accessed (push/pop) by our current thread.
523 TaskQueue work_queue_;
[email protected]b0992172008-10-27 18:54:18524
[email protected]752578562008-09-07 08:08:29525 // Contains delayed tasks, sorted by their 'delayed_run_time' property.
526 DelayedTaskQueue delayed_work_queue_;
initial.commitd7cae122008-07-26 21:49:38527
[email protected]a8f7d3d2010-11-04 23:23:42528 // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
[email protected]7e7fab42010-11-06 22:23:29529 base::TimeTicks recent_time_;
[email protected]a8f7d3d2010-11-04 23:23:42530
[email protected]752578562008-09-07 08:08:29531 // A queue of non-nestable tasks that we had to defer because when it came
532 // time to execute them we were in a nested message loop. They will execute
533 // once we're out of nested message loops.
534 TaskQueue deferred_non_nestable_work_queue_;
initial.commitd7cae122008-07-26 21:49:38535
[email protected]fc7fb6e2008-08-16 03:09:05536 scoped_refptr<base::MessagePump> pump_;
[email protected]ee132ad2008-08-06 21:27:02537
[email protected]2a127252008-08-05 23:16:41538 ObserverList<DestructionObserver> destruction_observers_;
[email protected]001747c2008-09-10 00:37:07539
initial.commitd7cae122008-07-26 21:49:38540 // A recursion block that prevents accidentally running additonal tasks when
541 // insider a (accidentally induced?) nested message pump.
542 bool nestable_tasks_allowed_;
543
544 bool exception_restoration_;
545
initial.commitd7cae122008-07-26 21:49:38546 std::string thread_name_;
547 // A profiling histogram showing the counts of various messages and events.
[email protected]81ce9f3b2011-04-05 04:48:53548 base::Histogram* message_histogram_;
initial.commitd7cae122008-07-26 21:49:38549
550 // A null terminated list which creates an incoming_queue of tasks that are
[email protected]242c4bd2011-02-25 18:43:23551 // acquired under a mutex for processing on this instance's thread. These
[email protected]b224f792011-04-20 16:02:23552 // tasks have not yet been sorted out into items for our work_queue_ vs items
553 // that will be handled by the TimerManager.
initial.commitd7cae122008-07-26 21:49:38554 TaskQueue incoming_queue_;
555 // Protect access to incoming_queue_.
[email protected]8d6ab8f52011-01-26 00:53:48556 mutable base::Lock incoming_queue_lock_;
initial.commitd7cae122008-07-26 21:49:38557
[email protected]fc7fb6e2008-08-16 03:09:05558 RunState* state_;
initial.commitd7cae122008-07-26 21:49:38559
[email protected]b224f792011-04-20 16:02:23560 // The need for this variable is subtle. Please see implementation comments
561 // around where it is used.
562 bool should_leak_tasks_;
563
[email protected]57f030a2010-06-29 04:58:15564#if defined(OS_WIN)
565 base::TimeTicks high_resolution_timer_expiration_;
[email protected]2ec01fe2011-03-24 03:40:28566 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
567 // which enter a modal message loop.
568 bool os_modal_loop_;
[email protected]57f030a2010-06-29 04:58:15569#endif
570
[email protected]752578562008-09-07 08:08:29571 // The next sequence number to use for delayed tasks.
572 int next_sequence_num_;
573
[email protected]9cfb89a2010-06-09 21:20:41574 ObserverList<TaskObserver> task_observers_;
575
[email protected]26fbf802011-03-25 18:48:03576 private:
[email protected]fc7fb6e2008-08-16 03:09:05577 DISALLOW_COPY_AND_ASSIGN(MessageLoop);
initial.commitd7cae122008-07-26 21:49:38578};
579
[email protected]4d9bdfaf2008-08-26 05:53:57580//-----------------------------------------------------------------------------
581// MessageLoopForUI extends MessageLoop with methods that are particular to a
582// MessageLoop instantiated with TYPE_UI.
583//
584// This class is typically used like so:
585// MessageLoopForUI::current()->...call some method...
586//
[email protected]0bea7252011-08-05 15:34:00587class BASE_EXPORT MessageLoopForUI : public MessageLoop {
[email protected]4d9bdfaf2008-08-26 05:53:57588 public:
589 MessageLoopForUI() : MessageLoop(TYPE_UI) {
590 }
license.botbf09a502008-08-24 00:55:55591
[email protected]4d9bdfaf2008-08-26 05:53:57592 // Returns the MessageLoopForUI of the current thread.
593 static MessageLoopForUI* current() {
594 MessageLoop* loop = MessageLoop::current();
595 DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
596 return static_cast<MessageLoopForUI*>(loop);
597 }
598
599#if defined(OS_WIN)
[email protected]4d9bdfaf2008-08-26 05:53:57600 void DidProcessMessage(const MSG& message);
[email protected]9cfb89a2010-06-09 21:20:41601#endif // defined(OS_WIN)
[email protected]1a8f5d1d2008-09-25 20:33:04602
[email protected]61c86c62011-08-02 16:11:16603#if defined(OS_ANDROID)
604 // On Android, the UI message loop is handled by Java side. So Run() should
605 // never be called. Instead use Start(), which will forward all the native UI
606 // events to the Java message loop.
607 void Start();
608#elif !defined(OS_MACOSX)
[email protected]148d1052009-07-31 22:53:37609 // Please see message_pump_win/message_pump_glib for definitions of these
610 // methods.
611 void AddObserver(Observer* observer);
612 void RemoveObserver(Observer* observer);
613 void Run(Dispatcher* dispatcher);
614
[email protected]1a8f5d1d2008-09-25 20:33:04615 protected:
616 // TODO(rvargas): Make this platform independent.
[email protected]17b89142008-11-07 21:52:15617 base::MessagePumpForUI* pump_ui() {
[email protected]1a8f5d1d2008-09-25 20:33:04618 return static_cast<base::MessagePumpForUI*>(pump_.get());
619 }
[email protected]9cfb89a2010-06-09 21:20:41620#endif // !defined(OS_MACOSX)
[email protected]4d9bdfaf2008-08-26 05:53:57621};
622
623// Do not add any member variables to MessageLoopForUI! This is important b/c
624// MessageLoopForUI is often allocated via MessageLoop(TYPE_UI). Any extra
625// data that you need should be stored on the MessageLoop's pump_ instance.
626COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
627 MessageLoopForUI_should_not_have_extra_member_variables);
628
629//-----------------------------------------------------------------------------
630// MessageLoopForIO extends MessageLoop with methods that are particular to a
631// MessageLoop instantiated with TYPE_IO.
632//
633// This class is typically used like so:
634// MessageLoopForIO::current()->...call some method...
635//
[email protected]0bea7252011-08-05 15:34:00636class BASE_EXPORT MessageLoopForIO : public MessageLoop {
[email protected]4d9bdfaf2008-08-26 05:53:57637 public:
[email protected]9cfb89a2010-06-09 21:20:41638#if defined(OS_WIN)
639 typedef base::MessagePumpForIO::IOHandler IOHandler;
640 typedef base::MessagePumpForIO::IOContext IOContext;
641 typedef base::MessagePumpForIO::IOObserver IOObserver;
642#elif defined(OS_POSIX)
643 typedef base::MessagePumpLibevent::Watcher Watcher;
644 typedef base::MessagePumpLibevent::FileDescriptorWatcher
645 FileDescriptorWatcher;
646 typedef base::MessagePumpLibevent::IOObserver IOObserver;
647
648 enum Mode {
649 WATCH_READ = base::MessagePumpLibevent::WATCH_READ,
650 WATCH_WRITE = base::MessagePumpLibevent::WATCH_WRITE,
651 WATCH_READ_WRITE = base::MessagePumpLibevent::WATCH_READ_WRITE
652 };
653
654#endif
655
[email protected]4d9bdfaf2008-08-26 05:53:57656 MessageLoopForIO() : MessageLoop(TYPE_IO) {
657 }
658
659 // Returns the MessageLoopForIO of the current thread.
660 static MessageLoopForIO* current() {
661 MessageLoop* loop = MessageLoop::current();
662 DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
663 return static_cast<MessageLoopForIO*>(loop);
664 }
665
[email protected]9cfb89a2010-06-09 21:20:41666 void AddIOObserver(IOObserver* io_observer) {
667 pump_io()->AddIOObserver(io_observer);
668 }
[email protected]941281482010-06-09 05:10:48669
[email protected]9cfb89a2010-06-09 21:20:41670 void RemoveIOObserver(IOObserver* io_observer) {
671 pump_io()->RemoveIOObserver(io_observer);
672 }
673
674#if defined(OS_WIN)
[email protected]4d9bdfaf2008-08-26 05:53:57675 // Please see MessagePumpWin for definitions of these methods.
[email protected]32cda29d2008-10-09 23:58:43676 void RegisterIOHandler(HANDLE file_handle, IOHandler* handler);
[email protected]17b89142008-11-07 21:52:15677 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
[email protected]36987e92008-09-18 18:46:26678
[email protected]1a8f5d1d2008-09-25 20:33:04679 protected:
680 // TODO(rvargas): Make this platform independent.
681 base::MessagePumpForIO* pump_io() {
682 return static_cast<base::MessagePumpForIO*>(pump_.get());
683 }
684
[email protected]36987e92008-09-18 18:46:26685#elif defined(OS_POSIX)
[email protected]e45e6c02008-12-15 22:02:17686 // Please see MessagePumpLibevent for definition.
687 bool WatchFileDescriptor(int fd,
688 bool persistent,
689 Mode mode,
690 FileDescriptorWatcher *controller,
691 Watcher *delegate);
[email protected]9cfb89a2010-06-09 21:20:41692
693 private:
694 base::MessagePumpLibevent* pump_io() {
695 return static_cast<base::MessagePumpLibevent*>(pump_.get());
696 }
[email protected]1a8f5d1d2008-09-25 20:33:04697#endif // defined(OS_POSIX)
[email protected]4d9bdfaf2008-08-26 05:53:57698};
699
700// Do not add any member variables to MessageLoopForIO! This is important b/c
701// MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra
702// data that you need should be stored on the MessageLoop's pump_ instance.
703COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
704 MessageLoopForIO_should_not_have_extra_member_variables);
705
706#endif // BASE_MESSAGE_LOOP_H_