message_loop.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef BASE_MESSAGE_LOOP_H_ 6#define BASE_MESSAGE_LOOP_H_ 7#pragma once 8 9#include <queue> 10#include <string> 11 12#include "base/basictypes.h" 13#include "base/lock.h" 14#include "base/message_pump.h" 15#include "base/observer_list.h" 16#include "base/ref_counted.h" 17#include "base/task.h" 18 19#if defined(OS_WIN) 20// We need this to declare base::MessagePumpWin::Dispatcher, which we should 21// really just eliminate. 22#include "base/message_pump_win.h" 23#elif defined(OS_POSIX) 24#include "base/message_pump_libevent.h" 25#if !defined(OS_MACOSX) 26#include "base/message_pump_glib.h" 27#endif 28#endif 29 30class Histogram; 31 32// A MessageLoop is used to process events for a particular thread. There is 33// at most one MessageLoop instance per thread. 34// 35// Events include at a minimum Task instances submitted to PostTask or those 36// managed by TimerManager. Depending on the type of message pump used by the 37// MessageLoop other events such as UI messages may be processed. On Windows 38// APC calls (as time permits) and signals sent to a registered set of HANDLEs 39// may also be processed. 40// 41// NOTE: Unless otherwise specified, a MessageLoop's methods may only be called 42// on the thread where the MessageLoop's Run method executes. 43// 44// NOTE: MessageLoop has task reentrancy protection. This means that if a 45// task is being processed, a second task cannot start until the first task is 46// finished. Reentrancy can happen when processing a task, and an inner 47// message pump is created. That inner pump then processes native messages 48// which could implicitly start an inner task. Inner message pumps are created 49// with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions 50// (DoDragDrop), printer functions (StartDoc) and *many* others. 51// 52// Sample workaround when inner task processing is needed: 53// bool old_state = MessageLoop::current()->NestableTasksAllowed(); 54// MessageLoop::current()->SetNestableTasksAllowed(true); 55// HRESULT hr = DoDragDrop(...); // Implicitly runs a modal message loop here. 56// MessageLoop::current()->SetNestableTasksAllowed(old_state); 57// // Process hr (the result returned by DoDragDrop(). 58// 59// Please be SURE your task is reentrant (nestable) and all global variables 60// are stable and accessible before calling SetNestableTasksAllowed(true). 61// 62class MessageLoop : public base::MessagePump::Delegate { 63 public: 64 // A TaskObserver is an object that receives task notifications from the 65 // MessageLoop. 66 // 67 // NOTE: A TaskObserver implementation should be extremely fast! 68 class TaskObserver { 69 public: 70 TaskObserver(); 71 72 // This method is called before processing a task. 73 virtual void WillProcessTask(base::TimeTicks birth_time) = 0; 74 75 // This method is called after processing a task. 76 virtual void DidProcessTask() = 0; 77 78 protected: 79 virtual ~TaskObserver(); 80 }; 81 82 static void EnableHistogrammer(bool enable_histogrammer); 83 84 // A DestructionObserver is notified when the current MessageLoop is being 85 // destroyed. These obsevers are notified prior to MessageLoop::current() 86 // being changed to return NULL. This gives interested parties the chance to 87 // do final cleanup that depends on the MessageLoop. 88 // 89 // NOTE: Any tasks posted to the MessageLoop during this notification will 90 // not be run. Instead, they will be deleted. 91 // 92 class DestructionObserver { 93 public: 94 virtual void WillDestroyCurrentMessageLoop() = 0; 95 96 protected: 97 virtual ~DestructionObserver(); 98 }; 99 100 // Add a DestructionObserver, which will start receiving notifications 101 // immediately. 102 void AddDestructionObserver(DestructionObserver* destruction_observer); 103 104 // Remove a DestructionObserver. It is safe to call this method while a 105 // DestructionObserver is receiving a notification callback. 106 void RemoveDestructionObserver(DestructionObserver* destruction_observer); 107 108 // The "PostTask" family of methods call the task's Run method asynchronously 109 // from within a message loop at some point in the future. 110 // 111 // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed 112 // with normal UI or IO event processing. With the PostDelayedTask variant, 113 // tasks are called after at least approximately 'delay_ms' have elapsed. 114 // 115 // The NonNestable variants work similarly except that they promise never to 116 // dispatch the task from a nested invocation of MessageLoop::Run. Instead, 117 // such tasks get deferred until the top-most MessageLoop::Run is executing. 118 // 119 // The MessageLoop takes ownership of the Task, and deletes it after it has 120 // been Run(). 121 // 122 // NOTE: These methods may be called on any thread. The Task will be invoked 123 // on the thread that executes MessageLoop::Run(). 124 125 void PostTask( 126 const tracked_objects::Location& from_here, Task* task); 127 128 void PostDelayedTask( 129 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); 130 131 void PostNonNestableTask( 132 const tracked_objects::Location& from_here, Task* task); 133 134 void PostNonNestableDelayedTask( 135 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); 136 137 // A variant on PostTask that deletes the given object. This is useful 138 // if the object needs to live until the next run of the MessageLoop (for 139 // example, deleting a RenderProcessHost from within an IPC callback is not 140 // good). 141 // 142 // NOTE: This method may be called on any thread. The object will be deleted 143 // on the thread that executes MessageLoop::Run(). If this is not the same 144 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit 145 // from RefCountedThreadSafe<T>! 146 template <class T> 147 void DeleteSoon(const tracked_objects::Location& from_here, T* object) { 148 PostNonNestableTask(from_here, new DeleteTask<T>(object)); 149 } 150 151 // A variant on PostTask that releases the given reference counted object 152 // (by calling its Release method). This is useful if the object needs to 153 // live until the next run of the MessageLoop, or if the object needs to be 154 // released on a particular thread. 155 // 156 // NOTE: This method may be called on any thread. The object will be 157 // released (and thus possibly deleted) on the thread that executes 158 // MessageLoop::Run(). If this is not the same as the thread that calls 159 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from 160 // RefCountedThreadSafe<T>! 161 template <class T> 162 void ReleaseSoon(const tracked_objects::Location& from_here, T* object) { 163 PostNonNestableTask(from_here, new ReleaseTask<T>(object)); 164 } 165 166 // Run the message loop. 167 void Run(); 168 169 // Process all pending tasks, windows messages, etc., but don't wait/sleep. 170 // Return as soon as all items that can be run are taken care of. 171 void RunAllPending(); 172 173 // Signals the Run method to return after it is done processing all pending 174 // messages. This method may only be called on the same thread that called 175 // Run, and Run must still be on the call stack. 176 // 177 // Use QuitTask if you need to Quit another thread's MessageLoop, but note 178 // that doing so is fairly dangerous if the target thread makes nested calls 179 // to MessageLoop::Run. The problem being that you won't know which nested 180 // run loop you are quiting, so be careful! 181 // 182 void Quit(); 183 184 // This method is a variant of Quit, that does not wait for pending messages 185 // to be processed before returning from Run. 186 void QuitNow(); 187 188 // Invokes Quit on the current MessageLoop when run. Useful to schedule an 189 // arbitrary MessageLoop to Quit. 190 class QuitTask : public Task { 191 public: 192 virtual void Run() { 193 MessageLoop::current()->Quit(); 194 } 195 }; 196 197 // A MessageLoop has a particular type, which indicates the set of 198 // asynchronous events it may process in addition to tasks and timers. 199 // 200 // TYPE_DEFAULT 201 // This type of ML only supports tasks and timers. 202 // 203 // TYPE_UI 204 // This type of ML also supports native UI events (e.g., Windows messages). 205 // See also MessageLoopForUI. 206 // 207 // TYPE_IO 208 // This type of ML also supports asynchronous IO. See also 209 // MessageLoopForIO. 210 // 211 enum Type { 212 TYPE_DEFAULT, 213 TYPE_UI, 214 TYPE_IO 215 }; 216 217 // Normally, it is not necessary to instantiate a MessageLoop. Instead, it 218 // is typical to make use of the current thread's MessageLoop instance. 219 explicit MessageLoop(Type type = TYPE_DEFAULT); 220 ~MessageLoop(); 221 222 // Returns the type passed to the constructor. 223 Type type() const { return type_; } 224 225 // Optional call to connect the thread name with this loop. 226 void set_thread_name(const std::string& thread_name) { 227 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; 228 thread_name_ = thread_name; 229 } 230 const std::string& thread_name() const { return thread_name_; } 231 232 // Returns the MessageLoop object for the current thread, or null if none. 233 static MessageLoop* current(); 234 235 // Enables or disables the recursive task processing. This happens in the case 236 // of recursive message loops. Some unwanted message loop may occurs when 237 // using common controls or printer functions. By default, recursive task 238 // processing is disabled. 239 // 240 // The specific case where tasks get queued is: 241 // - The thread is running a message loop. 242 // - It receives a task #1 and execute it. 243 // - The task #1 implicitly start a message loop, like a MessageBox in the 244 // unit test. This can also be StartDoc or GetSaveFileName. 245 // - The thread receives a task #2 before or while in this second message 246 // loop. 247 // - With NestableTasksAllowed set to true, the task #2 will run right away. 248 // Otherwise, it will get executed right after task #1 completes at "thread 249 // message loop level". 250 void SetNestableTasksAllowed(bool allowed); 251 bool NestableTasksAllowed() const; 252 253 // Enables nestable tasks on |loop| while in scope. 254 class ScopedNestableTaskAllower { 255 public: 256 explicit ScopedNestableTaskAllower(MessageLoop* loop) 257 : loop_(loop), 258 old_state_(loop_->NestableTasksAllowed()) { 259 loop_->SetNestableTasksAllowed(true); 260 } 261 ~ScopedNestableTaskAllower() { 262 loop_->SetNestableTasksAllowed(old_state_); 263 } 264 265 private: 266 MessageLoop* loop_; 267 bool old_state_; 268 }; 269 270 // Enables or disables the restoration during an exception of the unhandled 271 // exception filter that was active when Run() was called. This can happen 272 // if some third party code call SetUnhandledExceptionFilter() and never 273 // restores the previous filter. 274 void set_exception_restoration(bool restore) { 275 exception_restoration_ = restore; 276 } 277 278 // Returns true if we are currently running a nested message loop. 279 bool IsNested(); 280 281 // These functions can only be called on the same thread that |this| is 282 // running on. 283 void AddTaskObserver(TaskObserver* task_observer); 284 void RemoveTaskObserver(TaskObserver* task_observer); 285 286#if defined(OS_WIN) 287 typedef base::MessagePumpWin::Dispatcher Dispatcher; 288 typedef base::MessagePumpForUI::Observer Observer; 289#elif !defined(OS_MACOSX) 290 typedef base::MessagePumpForUI::Dispatcher Dispatcher; 291 typedef base::MessagePumpForUI::Observer Observer; 292#endif 293 294 // Returns true if the message loop has high resolution timers enabled. 295 // Provided for testing. 296 bool high_resolution_timers_enabled() { 297#if defined(OS_WIN) 298 return !high_resolution_timer_expiration_.is_null(); 299#else 300 return true; 301#endif 302 } 303 304 // When we go into high resolution timer mode, we will stay in hi-res mode 305 // for at least 1s. 306 static const int kHighResolutionTimerModeLeaseTimeMs = 1000; 307 308 //---------------------------------------------------------------------------- 309 protected: 310 struct RunState { 311 // Used to count how many Run() invocations are on the stack. 312 int run_depth; 313 314 // Used to record that Quit() was called, or that we should quit the pump 315 // once it becomes idle. 316 bool quit_received; 317 318#if !defined(OS_MACOSX) 319 Dispatcher* dispatcher; 320#endif 321 }; 322 323 class AutoRunState : RunState { 324 public: 325 explicit AutoRunState(MessageLoop* loop); 326 ~AutoRunState(); 327 private: 328 MessageLoop* loop_; 329 RunState* previous_state_; 330 }; 331 332 // This structure is copied around by value. 333 struct PendingTask { 334 Task* task; // The task to run. 335 base::Time delayed_run_time; // The time when the task should be run. 336 int sequence_num; // Used to facilitate sorting by run time. 337 bool nestable; // True if OK to dispatch from a nested loop. 338 339 PendingTask(Task* task, bool nestable) 340 : task(task), sequence_num(0), nestable(nestable) { 341 } 342 343 // Used to support sorting. 344 bool operator<(const PendingTask& other) const; 345 }; 346 347 class TaskQueue : public std::queue<PendingTask> { 348 public: 349 void Swap(TaskQueue* queue) { 350 c.swap(queue->c); // Calls std::deque::swap 351 } 352 }; 353 354 typedef std::priority_queue<PendingTask> DelayedTaskQueue; 355 356#if defined(OS_WIN) 357 base::MessagePumpWin* pump_win() { 358 return static_cast<base::MessagePumpWin*>(pump_.get()); 359 } 360#elif defined(OS_POSIX) 361 base::MessagePumpLibevent* pump_libevent() { 362 return static_cast<base::MessagePumpLibevent*>(pump_.get()); 363 } 364#endif 365 366 // A function to encapsulate all the exception handling capability in the 367 // stacks around the running of a main message loop. It will run the message 368 // loop in a SEH try block or not depending on the set_SEH_restoration() 369 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). 370 void RunHandler(); 371 372#if defined(OS_WIN) 373 __declspec(noinline) void RunInternalInSEHFrame(); 374#endif 375 376 // A surrounding stack frame around the running of the message loop that 377 // supports all saving and restoring of state, as is needed for any/all (ugly) 378 // recursive calls. 379 void RunInternal(); 380 381 // Called to process any delayed non-nestable tasks. 382 bool ProcessNextDelayedNonNestableTask(); 383 384 //---------------------------------------------------------------------------- 385 // Run a work_queue_ task or new_task, and delete it (if it was processed by 386 // PostTask). If there are queued tasks, the oldest one is executed and 387 // new_task is queued. new_task is optional and can be NULL. In this NULL 388 // case, the method will run one pending task (if any exist). Returns true if 389 // it executes a task. Queued tasks accumulate only when there is a 390 // non-nestable task currently processing, in which case the new_task is 391 // appended to the list work_queue_. Such re-entrancy generally happens when 392 // an unrequested message pump (typical of a native dialog) is executing in 393 // the context of a task. 394 bool QueueOrRunTask(Task* new_task); 395 396 // Runs the specified task and deletes it. 397 void RunTask(Task* task); 398 399 // Calls RunTask or queues the pending_task on the deferred task list if it 400 // cannot be run right now. Returns true if the task was run. 401 bool DeferOrRunPendingTask(const PendingTask& pending_task); 402 403 // Adds the pending task to delayed_work_queue_. 404 void AddToDelayedWorkQueue(const PendingTask& pending_task); 405 406 // Load tasks from the incoming_queue_ into work_queue_ if the latter is 407 // empty. The former requires a lock to access, while the latter is directly 408 // accessible on this thread. 409 void ReloadWorkQueue(); 410 411 // Delete tasks that haven't run yet without running them. Used in the 412 // destructor to make sure all the task's destructors get called. Returns 413 // true if some work was done. 414 bool DeletePendingTasks(); 415 416 // Post a task to our incomming queue. 417 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, 418 int64 delay_ms, bool nestable); 419 420 // base::MessagePump::Delegate methods: 421 virtual bool DoWork(); 422 virtual bool DoDelayedWork(base::Time* next_delayed_work_time); 423 virtual bool DoIdleWork(); 424 425 // Start recording histogram info about events and action IF it was enabled 426 // and IF the statistics recorder can accept a registration of our histogram. 427 void StartHistogrammer(); 428 429 // Add occurence of event to our histogram, so that we can see what is being 430 // done in a specific MessageLoop instance (i.e., specific thread). 431 // If message_histogram_ is NULL, this is a no-op. 432 void HistogramEvent(int event); 433 434 Type type_; 435 436 // A list of tasks that need to be processed by this instance. Note that 437 // this queue is only accessed (push/pop) by our current thread. 438 TaskQueue work_queue_; 439 440 // Contains delayed tasks, sorted by their 'delayed_run_time' property. 441 DelayedTaskQueue delayed_work_queue_; 442 443 // A queue of non-nestable tasks that we had to defer because when it came 444 // time to execute them we were in a nested message loop. They will execute 445 // once we're out of nested message loops. 446 TaskQueue deferred_non_nestable_work_queue_; 447 448 scoped_refptr<base::MessagePump> pump_; 449 450 ObserverList<DestructionObserver> destruction_observers_; 451 452 // A recursion block that prevents accidentally running additonal tasks when 453 // insider a (accidentally induced?) nested message pump. 454 bool nestable_tasks_allowed_; 455 456 bool exception_restoration_; 457 458 std::string thread_name_; 459 // A profiling histogram showing the counts of various messages and events. 460 scoped_refptr<Histogram> message_histogram_; 461 462 // A null terminated list which creates an incoming_queue of tasks that are 463 // aquired under a mutex for processing on this instance's thread. These tasks 464 // have not yet been sorted out into items for our work_queue_ vs items that 465 // will be handled by the TimerManager. 466 TaskQueue incoming_queue_; 467 // Protect access to incoming_queue_. 468 Lock incoming_queue_lock_; 469 470 RunState* state_; 471 472#if defined(OS_WIN) 473 base::TimeTicks high_resolution_timer_expiration_; 474#endif 475 476 // The next sequence number to use for delayed tasks. 477 int next_sequence_num_; 478 479 ObserverList<TaskObserver> task_observers_; 480 481 DISALLOW_COPY_AND_ASSIGN(MessageLoop); 482}; 483 484//----------------------------------------------------------------------------- 485// MessageLoopForUI extends MessageLoop with methods that are particular to a 486// MessageLoop instantiated with TYPE_UI. 487// 488// This class is typically used like so: 489// MessageLoopForUI::current()->...call some method... 490// 491class MessageLoopForUI : public MessageLoop { 492 public: 493 MessageLoopForUI() : MessageLoop(TYPE_UI) { 494 } 495 496 // Returns the MessageLoopForUI of the current thread. 497 static MessageLoopForUI* current() { 498 MessageLoop* loop = MessageLoop::current(); 499 //DCHECK_EQ(MessageLoop::TYPE_UI, loop->type()); 500 return static_cast<MessageLoopForUI*>(loop); 501 } 502 503#if defined(OS_WIN) 504 void DidProcessMessage(const MSG& message); 505#endif // defined(OS_WIN) 506 507#if !defined(OS_MACOSX) 508 // Please see message_pump_win/message_pump_glib for definitions of these 509 // methods. 510 void AddObserver(Observer* observer); 511 void RemoveObserver(Observer* observer); 512 void Run(Dispatcher* dispatcher); 513 514 protected: 515 // TODO(rvargas): Make this platform independent. 516 base::MessagePumpForUI* pump_ui() { 517 return static_cast<base::MessagePumpForUI*>(pump_.get()); 518 } 519#endif // !defined(OS_MACOSX) 520}; 521 522// Do not add any member variables to MessageLoopForUI! This is important b/c 523// MessageLoopForUI is often allocated via MessageLoop(TYPE_UI). Any extra 524// data that you need should be stored on the MessageLoop's pump_ instance. 525COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI), 526 MessageLoopForUI_should_not_have_extra_member_variables); 527 528//----------------------------------------------------------------------------- 529// MessageLoopForIO extends MessageLoop with methods that are particular to a 530// MessageLoop instantiated with TYPE_IO. 531// 532// This class is typically used like so: 533// MessageLoopForIO::current()->...call some method... 534// 535class MessageLoopForIO : public MessageLoop { 536 public: 537#if defined(OS_WIN) 538 typedef base::MessagePumpForIO::IOHandler IOHandler; 539 typedef base::MessagePumpForIO::IOContext IOContext; 540 typedef base::MessagePumpForIO::IOObserver IOObserver; 541#elif defined(OS_POSIX) 542 typedef base::MessagePumpLibevent::Watcher Watcher; 543 typedef base::MessagePumpLibevent::FileDescriptorWatcher 544 FileDescriptorWatcher; 545 typedef base::MessagePumpLibevent::IOObserver IOObserver; 546 547 enum Mode { 548 WATCH_READ = base::MessagePumpLibevent::WATCH_READ, 549 WATCH_WRITE = base::MessagePumpLibevent::WATCH_WRITE, 550 WATCH_READ_WRITE = base::MessagePumpLibevent::WATCH_READ_WRITE 551 }; 552 553#endif 554 555 MessageLoopForIO() : MessageLoop(TYPE_IO) { 556 } 557 558 // Returns the MessageLoopForIO of the current thread. 559 static MessageLoopForIO* current() { 560 MessageLoop* loop = MessageLoop::current(); 561 //DCHECK_EQ(MessageLoop::TYPE_IO, loop->type()); 562 return static_cast<MessageLoopForIO*>(loop); 563 } 564 565 void AddIOObserver(IOObserver* io_observer) { 566 pump_io()->AddIOObserver(io_observer); 567 } 568 569 void RemoveIOObserver(IOObserver* io_observer) { 570 pump_io()->RemoveIOObserver(io_observer); 571 } 572 573#if defined(OS_WIN) 574 // Please see MessagePumpWin for definitions of these methods. 575 void RegisterIOHandler(HANDLE file_handle, IOHandler* handler); 576 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter); 577 578 protected: 579 // TODO(rvargas): Make this platform independent. 580 base::MessagePumpForIO* pump_io() { 581 return static_cast<base::MessagePumpForIO*>(pump_.get()); 582 } 583 584#elif defined(OS_POSIX) 585 // Please see MessagePumpLibevent for definition. 586 bool WatchFileDescriptor(int fd, 587 bool persistent, 588 Mode mode, 589 FileDescriptorWatcher *controller, 590 Watcher *delegate); 591 592 private: 593 base::MessagePumpLibevent* pump_io() { 594 return static_cast<base::MessagePumpLibevent*>(pump_.get()); 595 } 596#endif // defined(OS_POSIX) 597}; 598 599// Do not add any member variables to MessageLoopForIO! This is important b/c 600// MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra 601// data that you need should be stored on the MessageLoop's pump_ instance. 602COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), 603 MessageLoopForIO_should_not_have_extra_member_variables); 604 605#endif // BASE_MESSAGE_LOOP_H_ 606