Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_MESSAGE_LOOP_H_ | 5 #ifndef BASE_MESSAGE_LOOP_H_ |
| 6 #define BASE_MESSAGE_LOOP_H_ | 6 #define BASE_MESSAGE_LOOP_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <queue> | 9 #include <queue> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "base/base_api.h" | 12 #include "base/base_api.h" |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/callback.h" | |
| 14 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 15 #include "base/message_pump.h" | 16 #include "base/message_pump.h" |
| 16 #include "base/observer_list.h" | 17 #include "base/observer_list.h" |
| 17 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
| 18 #include "base/task.h" | 19 #include "base/task.h" |
| 20 #include "base/time.h" | |
| 21 #include "base/tracked.h" | |
| 19 | 22 |
| 20 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
| 21 // We need this to declare base::MessagePumpWin::Dispatcher, which we should | 24 // We need this to declare base::MessagePumpWin::Dispatcher, which we should |
| 22 // really just eliminate. | 25 // really just eliminate. |
| 23 #include "base/message_pump_win.h" | 26 #include "base/message_pump_win.h" |
| 24 #elif defined(OS_POSIX) | 27 #elif defined(OS_POSIX) |
| 25 #include "base/message_pump_libevent.h" | 28 #include "base/message_pump_libevent.h" |
| 26 #if !defined(OS_MACOSX) | 29 #if !defined(OS_MACOSX) |
| 27 #include "base/message_pump_glib.h" | 30 #include "base/message_pump_glib.h" |
| 28 typedef struct _XDisplay Display; | 31 typedef struct _XDisplay Display; |
| 29 #endif | 32 #endif |
| 30 #endif | 33 #endif |
| 31 #if defined(TOUCH_UI) | 34 #if defined(TOUCH_UI) |
| 32 #include "base/message_pump_glib_x_dispatch.h" | 35 #include "base/message_pump_glib_x_dispatch.h" |
| 33 #endif | 36 #endif |
| 34 | 37 |
| 35 namespace base { | 38 namespace base { |
| 36 class Histogram; | 39 class Histogram; |
| 37 } | 40 } |
| 38 | 41 |
| 42 #if defined(TRACK_ALL_TASK_OBJECTS) | |
| 43 namespace tracked_objects { | |
| 44 class Births; | |
| 45 } | |
| 46 #endif // defined(TRACK_ALL_TASK_OBJECTS) | |
| 47 | |
| 39 // A MessageLoop is used to process events for a particular thread. There is | 48 // A MessageLoop is used to process events for a particular thread. There is |
| 40 // at most one MessageLoop instance per thread. | 49 // at most one MessageLoop instance per thread. |
| 41 // | 50 // |
| 42 // Events include at a minimum Task instances submitted to PostTask or those | 51 // Events include at a minimum Task instances submitted to PostTask or those |
| 43 // managed by TimerManager. Depending on the type of message pump used by the | 52 // managed by TimerManager. Depending on the type of message pump used by the |
| 44 // MessageLoop other events such as UI messages may be processed. On Windows | 53 // MessageLoop other events such as UI messages may be processed. On Windows |
| 45 // APC calls (as time permits) and signals sent to a registered set of HANDLEs | 54 // APC calls (as time permits) and signals sent to a registered set of HANDLEs |
| 46 // may also be processed. | 55 // may also be processed. |
| 47 // | 56 // |
| 48 // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called | 57 // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 const tracked_objects::Location& from_here, Task* task); | 164 const tracked_objects::Location& from_here, Task* task); |
| 156 | 165 |
| 157 void PostDelayedTask( | 166 void PostDelayedTask( |
| 158 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); | 167 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); |
| 159 | 168 |
| 160 void PostNonNestableTask( | 169 void PostNonNestableTask( |
| 161 const tracked_objects::Location& from_here, Task* task); | 170 const tracked_objects::Location& from_here, Task* task); |
| 162 | 171 |
| 163 void PostNonNestableDelayedTask( | 172 void PostNonNestableDelayedTask( |
| 164 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); | 173 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); |
| 165 | 174 |
|
darin (slow to review)
2011/04/15 18:35:36
I think you should add some kind of TODO comment h
awong
2011/04/15 18:45:57
Done.
| |
| 175 void PostTask( | |
| 176 const tracked_objects::Location& from_here, | |
| 177 const base::Closure& task); | |
| 178 | |
| 179 void PostDelayedTask( | |
| 180 const tracked_objects::Location& from_here, | |
| 181 const base::Closure& task, int64 delay_ms); | |
| 182 | |
| 183 void PostNonNestableTask( | |
| 184 const tracked_objects::Location& from_here, | |
| 185 const base::Closure& task); | |
| 186 | |
| 187 void PostNonNestableDelayedTask( | |
| 188 const tracked_objects::Location& from_here, | |
| 189 const base::Closure& task, int64 delay_ms); | |
| 190 | |
| 166 // A variant on PostTask that deletes the given object. This is useful | 191 // A variant on PostTask that deletes the given object. This is useful |
| 167 // if the object needs to live until the next run of the MessageLoop (for | 192 // if the object needs to live until the next run of the MessageLoop (for |
| 168 // example, deleting a RenderProcessHost from within an IPC callback is not | 193 // example, deleting a RenderProcessHost from within an IPC callback is not |
| 169 // good). | 194 // good). |
| 170 // | 195 // |
| 171 // NOTE: This method may be called on any thread. The object will be deleted | 196 // NOTE: This method may be called on any thread. The object will be deleted |
| 172 // on the thread that executes MessageLoop::Run(). If this is not the same | 197 // on the thread that executes MessageLoop::Run(). If this is not the same |
| 173 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit | 198 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit |
| 174 // from RefCountedThreadSafe<T>! | 199 // from RefCountedThreadSafe<T>! |
| 175 template <class T> | 200 template <class T> |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 282 | 307 |
| 283 // A TaskObserver is an object that receives task notifications from the | 308 // A TaskObserver is an object that receives task notifications from the |
| 284 // MessageLoop. | 309 // MessageLoop. |
| 285 // | 310 // |
| 286 // NOTE: A TaskObserver implementation should be extremely fast! | 311 // NOTE: A TaskObserver implementation should be extremely fast! |
| 287 class BASE_API TaskObserver { | 312 class BASE_API TaskObserver { |
| 288 public: | 313 public: |
| 289 TaskObserver(); | 314 TaskObserver(); |
| 290 | 315 |
| 291 // This method is called before processing a task. | 316 // This method is called before processing a task. |
| 292 virtual void WillProcessTask(const Task* task) = 0; | 317 virtual void WillProcessTask(base::TimeTicks time_posted) = 0; |
| 293 | 318 |
| 294 // This method is called after processing a task. | 319 // This method is called after processing a task. |
| 295 virtual void DidProcessTask(const Task* task) = 0; | 320 virtual void DidProcessTask(base::TimeTicks time_posted) = 0; |
| 296 | 321 |
| 297 protected: | 322 protected: |
| 298 virtual ~TaskObserver(); | 323 virtual ~TaskObserver(); |
| 299 }; | 324 }; |
| 300 | 325 |
| 301 // These functions can only be called on the same thread that |this| is | 326 // These functions can only be called on the same thread that |this| is |
| 302 // running on. | 327 // running on. |
| 303 void AddTaskObserver(TaskObserver* task_observer); | 328 void AddTaskObserver(TaskObserver* task_observer); |
| 304 void RemoveTaskObserver(TaskObserver* task_observer); | 329 void RemoveTaskObserver(TaskObserver* task_observer); |
| 305 | 330 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 public: | 374 public: |
| 350 explicit AutoRunState(MessageLoop* loop); | 375 explicit AutoRunState(MessageLoop* loop); |
| 351 ~AutoRunState(); | 376 ~AutoRunState(); |
| 352 private: | 377 private: |
| 353 MessageLoop* loop_; | 378 MessageLoop* loop_; |
| 354 RunState* previous_state_; | 379 RunState* previous_state_; |
| 355 }; | 380 }; |
| 356 | 381 |
| 357 // This structure is copied around by value. | 382 // This structure is copied around by value. |
| 358 struct PendingTask { | 383 struct PendingTask { |
| 359 PendingTask(Task* task, bool nestable) | 384 PendingTask(const base::Closure& task, |
| 360 : task(task), sequence_num(0), nestable(nestable) { | 385 const tracked_objects::Location& posted_from, |
| 361 } | 386 base::TimeTicks delayed_run_time, |
| 387 bool nestable); | |
| 362 | 388 |
| 363 // Used to support sorting. | 389 // Used to support sorting. |
| 364 bool operator<(const PendingTask& other) const; | 390 bool operator<(const PendingTask& other) const; |
| 365 | 391 |
| 366 Task* task; // The task to run. | 392 // The task to run. |
| 367 base::TimeTicks delayed_run_time; // The time when the task should be run. | 393 base::Closure task; |
| 368 int sequence_num; // Secondary sort key for run time. | 394 |
| 369 bool nestable; // OK to dispatch from a nested loop. | 395 #if defined(TRACK_ALL_TASK_OBJECTS) |
| 396 // Counter for location where the Closure was posted from. | |
| 397 tracked_objects::Births* post_births; | |
| 398 #endif // defined(TRACK_ALL_TASK_OBJECTS) | |
| 399 | |
| 400 // Time this PendingTask was posted. | |
| 401 base::TimeTicks time_posted; | |
| 402 | |
| 403 // The time when the task should be run. | |
| 404 base::TimeTicks delayed_run_time; | |
| 405 | |
| 406 // Secondary sort key for run time. | |
| 407 int sequence_num; | |
| 408 | |
| 409 // OK to dispatch from a nested loop. | |
| 410 bool nestable; | |
| 370 }; | 411 }; |
| 371 | 412 |
| 372 class TaskQueue : public std::queue<PendingTask> { | 413 class TaskQueue : public std::queue<PendingTask> { |
| 373 public: | 414 public: |
| 374 void Swap(TaskQueue* queue) { | 415 void Swap(TaskQueue* queue) { |
| 375 c.swap(queue->c); // Calls std::deque::swap | 416 c.swap(queue->c); // Calls std::deque::swap |
| 376 } | 417 } |
| 377 }; | 418 }; |
| 378 | 419 |
| 379 typedef std::priority_queue<PendingTask> DelayedTaskQueue; | 420 typedef std::priority_queue<PendingTask> DelayedTaskQueue; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 399 #endif | 440 #endif |
| 400 | 441 |
| 401 // A surrounding stack frame around the running of the message loop that | 442 // A surrounding stack frame around the running of the message loop that |
| 402 // supports all saving and restoring of state, as is needed for any/all (ugly) | 443 // supports all saving and restoring of state, as is needed for any/all (ugly) |
| 403 // recursive calls. | 444 // recursive calls. |
| 404 void RunInternal(); | 445 void RunInternal(); |
| 405 | 446 |
| 406 // Called to process any delayed non-nestable tasks. | 447 // Called to process any delayed non-nestable tasks. |
| 407 bool ProcessNextDelayedNonNestableTask(); | 448 bool ProcessNextDelayedNonNestableTask(); |
| 408 | 449 |
| 409 // Runs the specified task and deletes it. | 450 // Runs the specified PendingTask. |
| 410 void RunTask(Task* task); | 451 void RunTask(const PendingTask& pending_task); |
| 411 | 452 |
| 412 // Calls RunTask or queues the pending_task on the deferred task list if it | 453 // Calls RunTask or queues the pending_task on the deferred task list if it |
| 413 // cannot be run right now. Returns true if the task was run. | 454 // cannot be run right now. Returns true if the task was run. |
| 414 bool DeferOrRunPendingTask(const PendingTask& pending_task); | 455 bool DeferOrRunPendingTask(const PendingTask& pending_task); |
| 415 | 456 |
| 416 // Adds the pending task to delayed_work_queue_. | 457 // Adds the pending task to delayed_work_queue_. |
| 417 void AddToDelayedWorkQueue(const PendingTask& pending_task); | 458 void AddToDelayedWorkQueue(const PendingTask& pending_task); |
| 418 | 459 |
| 460 // Adds the pending task to our incoming_queue_. | |
| 461 // | |
| 462 // Caller retains ownership of |pending_task|, but this function will | |
| 463 // reset the value of pending_task->task. This is needed to ensure | |
| 464 // that the posting call stack does not retain pending_task->task | |
| 465 // beyond this function call. | |
| 466 void AddToIncomingQueue(PendingTask* pending_task); | |
| 467 | |
| 419 // Load tasks from the incoming_queue_ into work_queue_ if the latter is | 468 // Load tasks from the incoming_queue_ into work_queue_ if the latter is |
| 420 // empty. The former requires a lock to access, while the latter is directly | 469 // empty. The former requires a lock to access, while the latter is directly |
| 421 // accessible on this thread. | 470 // accessible on this thread. |
| 422 void ReloadWorkQueue(); | 471 void ReloadWorkQueue(); |
| 423 | 472 |
| 424 // Delete tasks that haven't run yet without running them. Used in the | 473 // Delete tasks that haven't run yet without running them. Used in the |
| 425 // destructor to make sure all the task's destructors get called. Returns | 474 // destructor to make sure all the task's destructors get called. Returns |
| 426 // true if some work was done. | 475 // true if some work was done. |
| 427 bool DeletePendingTasks(); | 476 bool DeletePendingTasks(); |
| 428 | 477 |
| 429 // Post a task to our incomming queue. | 478 // Calcuates the time at which a PendingTask should run. |
| 430 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, | 479 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms); |
| 431 int64 delay_ms, bool nestable); | |
| 432 | 480 |
| 433 // Start recording histogram info about events and action IF it was enabled | 481 // Start recording histogram info about events and action IF it was enabled |
| 434 // and IF the statistics recorder can accept a registration of our histogram. | 482 // and IF the statistics recorder can accept a registration of our histogram. |
| 435 void StartHistogrammer(); | 483 void StartHistogrammer(); |
| 436 | 484 |
| 437 // Add occurence of event to our histogram, so that we can see what is being | 485 // Add occurence of event to our histogram, so that we can see what is being |
| 438 // done in a specific MessageLoop instance (i.e., specific thread). | 486 // done in a specific MessageLoop instance (i.e., specific thread). |
| 439 // If message_histogram_ is NULL, this is a no-op. | 487 // If message_histogram_ is NULL, this is a no-op. |
| 440 void HistogramEvent(int event); | 488 void HistogramEvent(int event); |
| 441 | 489 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 470 bool nestable_tasks_allowed_; | 518 bool nestable_tasks_allowed_; |
| 471 | 519 |
| 472 bool exception_restoration_; | 520 bool exception_restoration_; |
| 473 | 521 |
| 474 std::string thread_name_; | 522 std::string thread_name_; |
| 475 // A profiling histogram showing the counts of various messages and events. | 523 // A profiling histogram showing the counts of various messages and events. |
| 476 base::Histogram* message_histogram_; | 524 base::Histogram* message_histogram_; |
| 477 | 525 |
| 478 // A null terminated list which creates an incoming_queue of tasks that are | 526 // A null terminated list which creates an incoming_queue of tasks that are |
| 479 // acquired under a mutex for processing on this instance's thread. These | 527 // acquired under a mutex for processing on this instance's thread. These |
| 480 // tasks have not yet been sorted out into items for our work_queue_ vs | 528 // tasks have not yet been sorted out into items for our work_queue_ vs items |
| 481 // items that will be handled by the TimerManager. | 529 // that will be handled by the TimerManager. |
| 482 TaskQueue incoming_queue_; | 530 TaskQueue incoming_queue_; |
| 483 // Protect access to incoming_queue_. | 531 // Protect access to incoming_queue_. |
| 484 mutable base::Lock incoming_queue_lock_; | 532 mutable base::Lock incoming_queue_lock_; |
| 485 | 533 |
| 486 RunState* state_; | 534 RunState* state_; |
| 487 | 535 |
| 536 bool should_leak_tasks_; | |
| 537 | |
| 488 #if defined(OS_WIN) | 538 #if defined(OS_WIN) |
| 489 base::TimeTicks high_resolution_timer_expiration_; | 539 base::TimeTicks high_resolution_timer_expiration_; |
| 490 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc | 540 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc |
| 491 // which enter a modal message loop. | 541 // which enter a modal message loop. |
| 492 bool os_modal_loop_; | 542 bool os_modal_loop_; |
| 493 #endif | 543 #endif |
| 494 | 544 |
| 495 // The next sequence number to use for delayed tasks. | 545 // The next sequence number to use for delayed tasks. |
| 496 int next_sequence_num_; | 546 int next_sequence_num_; |
| 497 | 547 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 628 #endif // defined(OS_POSIX) | 678 #endif // defined(OS_POSIX) |
| 629 }; | 679 }; |
| 630 | 680 |
| 631 // Do not add any member variables to MessageLoopForIO! This is important b/c | 681 // Do not add any member variables to MessageLoopForIO! This is important b/c |
| 632 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 682 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
| 633 // data that you need should be stored on the MessageLoop's pump_ instance. | 683 // data that you need should be stored on the MessageLoop's pump_ instance. |
| 634 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 684 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
| 635 MessageLoopForIO_should_not_have_extra_member_variables); | 685 MessageLoopForIO_should_not_have_extra_member_variables); |
| 636 | 686 |
| 637 #endif // BASE_MESSAGE_LOOP_H_ | 687 #endif // BASE_MESSAGE_LOOP_H_ |
| OLD | NEW |