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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 |
175 // TODO(ajwong): Remove the functions above once the Task -> Closure migration | |
176 // is complete. | |
177 // | |
178 // There are 2 sets of Post*Task functions, one which tasks the older Task* | |
joth
2011/04/16 15:11:57
nit: one which _takes_
awong
2011/04/17 00:34:57
Done.
| |
179 // function object representation, and one that task the newer base::Closure. | |
joth
2011/04/16 15:11:57
again, one that _takes_
awong
2011/04/17 00:34:57
Done.
| |
180 // We have this overload to allow a staged transition between the two systems. | |
181 // Once the transition is done, the functions above should be deleted. | |
182 void PostTask( | |
183 const tracked_objects::Location& from_here, | |
184 const base::Closure& task); | |
185 | |
186 void PostDelayedTask( | |
187 const tracked_objects::Location& from_here, | |
188 const base::Closure& task, int64 delay_ms); | |
189 | |
190 void PostNonNestableTask( | |
191 const tracked_objects::Location& from_here, | |
192 const base::Closure& task); | |
193 | |
194 void PostNonNestableDelayedTask( | |
195 const tracked_objects::Location& from_here, | |
196 const base::Closure& task, int64 delay_ms); | |
197 | |
166 // A variant on PostTask that deletes the given object. This is useful | 198 // 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 | 199 // 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 | 200 // example, deleting a RenderProcessHost from within an IPC callback is not |
169 // good). | 201 // good). |
170 // | 202 // |
171 // NOTE: This method may be called on any thread. The object will be deleted | 203 // 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 | 204 // 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 | 205 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit |
174 // from RefCountedThreadSafe<T>! | 206 // from RefCountedThreadSafe<T>! |
175 template <class T> | 207 template <class T> |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 | 314 |
283 // A TaskObserver is an object that receives task notifications from the | 315 // A TaskObserver is an object that receives task notifications from the |
284 // MessageLoop. | 316 // MessageLoop. |
285 // | 317 // |
286 // NOTE: A TaskObserver implementation should be extremely fast! | 318 // NOTE: A TaskObserver implementation should be extremely fast! |
287 class BASE_API TaskObserver { | 319 class BASE_API TaskObserver { |
288 public: | 320 public: |
289 TaskObserver(); | 321 TaskObserver(); |
290 | 322 |
291 // This method is called before processing a task. | 323 // This method is called before processing a task. |
292 virtual void WillProcessTask(const Task* task) = 0; | 324 virtual void WillProcessTask(base::TimeTicks time_posted) = 0; |
293 | 325 |
294 // This method is called after processing a task. | 326 // This method is called after processing a task. |
295 virtual void DidProcessTask(const Task* task) = 0; | 327 virtual void DidProcessTask(base::TimeTicks time_posted) = 0; |
296 | 328 |
297 protected: | 329 protected: |
298 virtual ~TaskObserver(); | 330 virtual ~TaskObserver(); |
299 }; | 331 }; |
300 | 332 |
301 // These functions can only be called on the same thread that |this| is | 333 // These functions can only be called on the same thread that |this| is |
302 // running on. | 334 // running on. |
303 void AddTaskObserver(TaskObserver* task_observer); | 335 void AddTaskObserver(TaskObserver* task_observer); |
304 void RemoveTaskObserver(TaskObserver* task_observer); | 336 void RemoveTaskObserver(TaskObserver* task_observer); |
305 | 337 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 public: | 381 public: |
350 explicit AutoRunState(MessageLoop* loop); | 382 explicit AutoRunState(MessageLoop* loop); |
351 ~AutoRunState(); | 383 ~AutoRunState(); |
352 private: | 384 private: |
353 MessageLoop* loop_; | 385 MessageLoop* loop_; |
354 RunState* previous_state_; | 386 RunState* previous_state_; |
355 }; | 387 }; |
356 | 388 |
357 // This structure is copied around by value. | 389 // This structure is copied around by value. |
358 struct PendingTask { | 390 struct PendingTask { |
359 PendingTask(Task* task, bool nestable) | 391 PendingTask(const base::Closure& task, |
360 : task(task), sequence_num(0), nestable(nestable) { | 392 const tracked_objects::Location& posted_from, |
361 } | 393 base::TimeTicks delayed_run_time, |
394 bool nestable); | |
362 | 395 |
363 // Used to support sorting. | 396 // Used to support sorting. |
364 bool operator<(const PendingTask& other) const; | 397 bool operator<(const PendingTask& other) const; |
365 | 398 |
366 Task* task; // The task to run. | 399 // The task to run. |
367 base::TimeTicks delayed_run_time; // The time when the task should be run. | 400 base::Closure task; |
368 int sequence_num; // Secondary sort key for run time. | 401 |
369 bool nestable; // OK to dispatch from a nested loop. | 402 #if defined(TRACK_ALL_TASK_OBJECTS) |
403 // Counter for location where the Closure was posted from. | |
404 tracked_objects::Births* post_births; | |
405 #endif // defined(TRACK_ALL_TASK_OBJECTS) | |
406 | |
407 // Time this PendingTask was posted. | |
408 base::TimeTicks time_posted; | |
409 | |
410 // The time when the task should be run. | |
411 base::TimeTicks delayed_run_time; | |
412 | |
413 // Secondary sort key for run time. | |
414 int sequence_num; | |
415 | |
416 // OK to dispatch from a nested loop. | |
417 bool nestable; | |
370 }; | 418 }; |
371 | 419 |
372 class TaskQueue : public std::queue<PendingTask> { | 420 class TaskQueue : public std::queue<PendingTask> { |
373 public: | 421 public: |
374 void Swap(TaskQueue* queue) { | 422 void Swap(TaskQueue* queue) { |
375 c.swap(queue->c); // Calls std::deque::swap | 423 c.swap(queue->c); // Calls std::deque::swap |
376 } | 424 } |
377 }; | 425 }; |
378 | 426 |
379 typedef std::priority_queue<PendingTask> DelayedTaskQueue; | 427 typedef std::priority_queue<PendingTask> DelayedTaskQueue; |
(...skipping 19 matching lines...) Expand all Loading... | |
399 #endif | 447 #endif |
400 | 448 |
401 // A surrounding stack frame around the running of the message loop that | 449 // 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) | 450 // supports all saving and restoring of state, as is needed for any/all (ugly) |
403 // recursive calls. | 451 // recursive calls. |
404 void RunInternal(); | 452 void RunInternal(); |
405 | 453 |
406 // Called to process any delayed non-nestable tasks. | 454 // Called to process any delayed non-nestable tasks. |
407 bool ProcessNextDelayedNonNestableTask(); | 455 bool ProcessNextDelayedNonNestableTask(); |
408 | 456 |
409 // Runs the specified task and deletes it. | 457 // Runs the specified PendingTask. |
410 void RunTask(Task* task); | 458 void RunTask(const PendingTask& pending_task); |
411 | 459 |
412 // Calls RunTask or queues the pending_task on the deferred task list if it | 460 // 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. | 461 // cannot be run right now. Returns true if the task was run. |
414 bool DeferOrRunPendingTask(const PendingTask& pending_task); | 462 bool DeferOrRunPendingTask(const PendingTask& pending_task); |
415 | 463 |
416 // Adds the pending task to delayed_work_queue_. | 464 // Adds the pending task to delayed_work_queue_. |
417 void AddToDelayedWorkQueue(const PendingTask& pending_task); | 465 void AddToDelayedWorkQueue(const PendingTask& pending_task); |
418 | 466 |
467 // Adds the pending task to our incoming_queue_. | |
468 // | |
469 // Caller retains ownership of |pending_task|, but this function will | |
470 // reset the value of pending_task->task. This is needed to ensure | |
471 // that the posting call stack does not retain pending_task->task | |
472 // beyond this function call. | |
473 void AddToIncomingQueue(PendingTask* pending_task); | |
474 | |
419 // Load tasks from the incoming_queue_ into work_queue_ if the latter is | 475 // 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 | 476 // empty. The former requires a lock to access, while the latter is directly |
421 // accessible on this thread. | 477 // accessible on this thread. |
422 void ReloadWorkQueue(); | 478 void ReloadWorkQueue(); |
423 | 479 |
424 // Delete tasks that haven't run yet without running them. Used in the | 480 // 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 | 481 // destructor to make sure all the task's destructors get called. Returns |
426 // true if some work was done. | 482 // true if some work was done. |
427 bool DeletePendingTasks(); | 483 bool DeletePendingTasks(); |
428 | 484 |
429 // Post a task to our incomming queue. | 485 // Calcuates the time at which a PendingTask should run. |
430 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, | 486 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms); |
431 int64 delay_ms, bool nestable); | |
432 | 487 |
433 // Start recording histogram info about events and action IF it was enabled | 488 // 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. | 489 // and IF the statistics recorder can accept a registration of our histogram. |
435 void StartHistogrammer(); | 490 void StartHistogrammer(); |
436 | 491 |
437 // Add occurence of event to our histogram, so that we can see what is being | 492 // 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). | 493 // done in a specific MessageLoop instance (i.e., specific thread). |
439 // If message_histogram_ is NULL, this is a no-op. | 494 // If message_histogram_ is NULL, this is a no-op. |
440 void HistogramEvent(int event); | 495 void HistogramEvent(int event); |
441 | 496 |
(...skipping 28 matching lines...) Expand all Loading... | |
470 bool nestable_tasks_allowed_; | 525 bool nestable_tasks_allowed_; |
471 | 526 |
472 bool exception_restoration_; | 527 bool exception_restoration_; |
473 | 528 |
474 std::string thread_name_; | 529 std::string thread_name_; |
475 // A profiling histogram showing the counts of various messages and events. | 530 // A profiling histogram showing the counts of various messages and events. |
476 base::Histogram* message_histogram_; | 531 base::Histogram* message_histogram_; |
477 | 532 |
478 // A null terminated list which creates an incoming_queue of tasks that are | 533 // 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 | 534 // 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 | 535 // tasks have not yet been sorted out into items for our work_queue_ vs items |
481 // items that will be handled by the TimerManager. | 536 // that will be handled by the TimerManager. |
482 TaskQueue incoming_queue_; | 537 TaskQueue incoming_queue_; |
483 // Protect access to incoming_queue_. | 538 // Protect access to incoming_queue_. |
484 mutable base::Lock incoming_queue_lock_; | 539 mutable base::Lock incoming_queue_lock_; |
485 | 540 |
486 RunState* state_; | 541 RunState* state_; |
487 | 542 |
543 bool should_leak_tasks_; | |
joth
2011/04/16 15:11:57
maybe worth putting a comment on this member, if j
awong
2011/04/17 00:34:57
Good idea! Comment added.
| |
544 | |
488 #if defined(OS_WIN) | 545 #if defined(OS_WIN) |
489 base::TimeTicks high_resolution_timer_expiration_; | 546 base::TimeTicks high_resolution_timer_expiration_; |
490 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc | 547 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc |
491 // which enter a modal message loop. | 548 // which enter a modal message loop. |
492 bool os_modal_loop_; | 549 bool os_modal_loop_; |
493 #endif | 550 #endif |
494 | 551 |
495 // The next sequence number to use for delayed tasks. | 552 // The next sequence number to use for delayed tasks. |
496 int next_sequence_num_; | 553 int next_sequence_num_; |
497 | 554 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
628 #endif // defined(OS_POSIX) | 685 #endif // defined(OS_POSIX) |
629 }; | 686 }; |
630 | 687 |
631 // Do not add any member variables to MessageLoopForIO! This is important b/c | 688 // Do not add any member variables to MessageLoopForIO! This is important b/c |
632 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 689 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
633 // data that you need should be stored on the MessageLoop's pump_ instance. | 690 // data that you need should be stored on the MessageLoop's pump_ instance. |
634 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 691 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
635 MessageLoopForIO_should_not_have_extra_member_variables); | 692 MessageLoopForIO_should_not_have_extra_member_variables); |
636 | 693 |
637 #endif // BASE_MESSAGE_LOOP_H_ | 694 #endif // BASE_MESSAGE_LOOP_H_ |
OLD | NEW |