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/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/callback.h" | |
13 #include "base/message_pump.h" | 14 #include "base/message_pump.h" |
14 #include "base/observer_list.h" | 15 #include "base/observer_list.h" |
15 #include "base/ref_counted.h" | 16 #include "base/ref_counted.h" |
16 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
17 #include "base/task.h" | 18 #include "base/task.h" |
18 | 19 |
19 #if defined(OS_WIN) | 20 #if defined(OS_WIN) |
20 // We need this to declare base::MessagePumpWin::Dispatcher, which we should | 21 // We need this to declare base::MessagePumpWin::Dispatcher, which we should |
21 // really just eliminate. | 22 // really just eliminate. |
22 #include "base/message_pump_win.h" | 23 #include "base/message_pump_win.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 | 155 |
155 void PostDelayedTask( | 156 void PostDelayedTask( |
156 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); | 157 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); |
157 | 158 |
158 void PostNonNestableTask( | 159 void PostNonNestableTask( |
159 const tracked_objects::Location& from_here, Task* task); | 160 const tracked_objects::Location& from_here, Task* task); |
160 | 161 |
161 void PostNonNestableDelayedTask( | 162 void PostNonNestableDelayedTask( |
162 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); | 163 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); |
163 | 164 |
165 void PostClosure( | |
166 const tracked_objects::Location& from_here, | |
167 const base::Closure& closure); | |
168 | |
169 void PostDelayedClosure( | |
170 const tracked_objects::Location& from_here, | |
171 const base::Closure& closure, int64 delay_ms); | |
172 | |
173 void PostNonNestableClosure( | |
174 const tracked_objects::Location& from_here, | |
175 const base::Closure& closure); | |
176 | |
177 void PostNonNestableDelayedClosure( | |
178 const tracked_objects::Location& from_here, | |
179 const base::Closure& closure, int64 delay_ms); | |
180 | |
164 // A variant on PostTask that deletes the given object. This is useful | 181 // A variant on PostTask that deletes the given object. This is useful |
165 // if the object needs to live until the next run of the MessageLoop (for | 182 // if the object needs to live until the next run of the MessageLoop (for |
166 // example, deleting a RenderProcessHost from within an IPC callback is not | 183 // example, deleting a RenderProcessHost from within an IPC callback is not |
167 // good). | 184 // good). |
168 // | 185 // |
169 // NOTE: This method may be called on any thread. The object will be deleted | 186 // NOTE: This method may be called on any thread. The object will be deleted |
170 // on the thread that executes MessageLoop::Run(). If this is not the same | 187 // on the thread that executes MessageLoop::Run(). If this is not the same |
171 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit | 188 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit |
172 // from RefCountedThreadSafe<T>! | 189 // from RefCountedThreadSafe<T>! |
173 template <class T> | 190 template <class T> |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 public: | 354 public: |
338 explicit AutoRunState(MessageLoop* loop); | 355 explicit AutoRunState(MessageLoop* loop); |
339 ~AutoRunState(); | 356 ~AutoRunState(); |
340 private: | 357 private: |
341 MessageLoop* loop_; | 358 MessageLoop* loop_; |
342 RunState* previous_state_; | 359 RunState* previous_state_; |
343 }; | 360 }; |
344 | 361 |
345 // This structure is copied around by value. | 362 // This structure is copied around by value. |
346 struct PendingTask { | 363 struct PendingTask { |
347 PendingTask(Task* task, bool nestable) | 364 PendingTask(Task* task, base::TimeTicks delayed_run_time, bool nestable) |
348 : task(task), sequence_num(0), nestable(nestable) { | 365 : task(task), delayed_run_time(delayed_run_time), sequence_num(0), |
366 nestable(nestable) { | |
367 } | |
368 | |
369 PendingTask(const base::Closure& closure, base::TimeTicks delayed_run_time, | |
370 bool nestable) | |
371 : task(NULL), closure(closure), delayed_run_time(delayed_run_time), | |
372 sequence_num(0), nestable(nestable) { | |
349 } | 373 } |
350 | 374 |
351 // Used to support sorting. | 375 // Used to support sorting. |
352 bool operator<(const PendingTask& other) const; | 376 bool operator<(const PendingTask& other) const; |
353 | 377 |
354 Task* task; // The task to run. | 378 Task* task; // The task to run. |
darin (slow to review)
2011/02/15 05:05:47
It would be nice to implement the old Task-based m
awong
2011/02/15 08:24:42
Hah...yes it would. I was initially thinking of a
| |
379 base::Closure closure; // The Closure to run if task == NULL. | |
355 base::TimeTicks delayed_run_time; // The time when the task should be run. | 380 base::TimeTicks delayed_run_time; // The time when the task should be run. |
356 int sequence_num; // Secondary sort key for run time. | 381 int sequence_num; // Secondary sort key for run time. |
357 bool nestable; // OK to dispatch from a nested loop. | 382 bool nestable; // OK to dispatch from a nested loop. |
358 }; | 383 }; |
359 | 384 |
360 class TaskQueue : public std::queue<PendingTask> { | 385 class TaskQueue : public std::queue<PendingTask> { |
361 public: | 386 public: |
362 void Swap(TaskQueue* queue) { | 387 void Swap(TaskQueue* queue) { |
363 c.swap(queue->c); // Calls std::deque::swap | 388 c.swap(queue->c); // Calls std::deque::swap |
364 } | 389 } |
(...skipping 25 matching lines...) Expand all Loading... | |
390 // supports all saving and restoring of state, as is needed for any/all (ugly) | 415 // supports all saving and restoring of state, as is needed for any/all (ugly) |
391 // recursive calls. | 416 // recursive calls. |
392 void RunInternal(); | 417 void RunInternal(); |
393 | 418 |
394 // Called to process any delayed non-nestable tasks. | 419 // Called to process any delayed non-nestable tasks. |
395 bool ProcessNextDelayedNonNestableTask(); | 420 bool ProcessNextDelayedNonNestableTask(); |
396 | 421 |
397 // Runs the specified task and deletes it. | 422 // Runs the specified task and deletes it. |
398 void RunTask(Task* task); | 423 void RunTask(Task* task); |
399 | 424 |
425 // Runs the specified Closure. | |
426 void RunClosure(const base::Closure& closure); | |
427 | |
400 // Calls RunTask or queues the pending_task on the deferred task list if it | 428 // Calls RunTask or queues the pending_task on the deferred task list if it |
401 // cannot be run right now. Returns true if the task was run. | 429 // cannot be run right now. Returns true if the task was run. |
402 bool DeferOrRunPendingTask(const PendingTask& pending_task); | 430 bool DeferOrRunPendingTask(const PendingTask& pending_task); |
403 | 431 |
404 // Adds the pending task to delayed_work_queue_. | 432 // Adds the pending task to delayed_work_queue_. |
405 void AddToDelayedWorkQueue(const PendingTask& pending_task); | 433 void AddToDelayedWorkQueue(const PendingTask& pending_task); |
406 | 434 |
435 // Adds the pending task to our incoming_queue_. | |
436 void AddToIncomingQueue(const PendingTask& pending_task); | |
437 | |
407 // Load tasks from the incoming_queue_ into work_queue_ if the latter is | 438 // Load tasks from the incoming_queue_ into work_queue_ if the latter is |
408 // empty. The former requires a lock to access, while the latter is directly | 439 // empty. The former requires a lock to access, while the latter is directly |
409 // accessible on this thread. | 440 // accessible on this thread. |
410 void ReloadWorkQueue(); | 441 void ReloadWorkQueue(); |
411 | 442 |
412 // Delete tasks that haven't run yet without running them. Used in the | 443 // Delete tasks that haven't run yet without running them. Used in the |
413 // destructor to make sure all the task's destructors get called. Returns | 444 // destructor to make sure all the task's destructors get called. Returns |
414 // true if some work was done. | 445 // true if some work was done. |
415 bool DeletePendingTasks(); | 446 bool DeletePendingTasks(); |
416 | 447 |
417 // Post a task to our incomming queue. | 448 // Calcuates the time at which a PendingTask should run. |
418 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, | 449 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms); |
419 int64 delay_ms, bool nestable); | |
420 | 450 |
421 // Start recording histogram info about events and action IF it was enabled | 451 // Start recording histogram info about events and action IF it was enabled |
422 // and IF the statistics recorder can accept a registration of our histogram. | 452 // and IF the statistics recorder can accept a registration of our histogram. |
423 void StartHistogrammer(); | 453 void StartHistogrammer(); |
424 | 454 |
425 // Add occurence of event to our histogram, so that we can see what is being | 455 // Add occurence of event to our histogram, so that we can see what is being |
426 // done in a specific MessageLoop instance (i.e., specific thread). | 456 // done in a specific MessageLoop instance (i.e., specific thread). |
427 // If message_histogram_ is NULL, this is a no-op. | 457 // If message_histogram_ is NULL, this is a no-op. |
428 void HistogramEvent(int event); | 458 void HistogramEvent(int event); |
429 | 459 |
(...skipping 27 matching lines...) Expand all Loading... | |
457 // insider a (accidentally induced?) nested message pump. | 487 // insider a (accidentally induced?) nested message pump. |
458 bool nestable_tasks_allowed_; | 488 bool nestable_tasks_allowed_; |
459 | 489 |
460 bool exception_restoration_; | 490 bool exception_restoration_; |
461 | 491 |
462 std::string thread_name_; | 492 std::string thread_name_; |
463 // A profiling histogram showing the counts of various messages and events. | 493 // A profiling histogram showing the counts of various messages and events. |
464 scoped_refptr<base::Histogram> message_histogram_; | 494 scoped_refptr<base::Histogram> message_histogram_; |
465 | 495 |
466 // A null terminated list which creates an incoming_queue of tasks that are | 496 // A null terminated list which creates an incoming_queue of tasks that are |
467 // acquired under a mutex for processing on this instance's thread. These task s | 497 // acquired under a mutex for processing on this instance's thread. These |
468 // have not yet been sorted out into items for our work_queue_ vs items that | 498 // tasks have not yet been sorted out into items for our work_queue_ vs items |
469 // will be handled by the TimerManager. | 499 // that will be handled by the TimerManager. |
470 TaskQueue incoming_queue_; | 500 TaskQueue incoming_queue_; |
471 // Protect access to incoming_queue_. | 501 // Protect access to incoming_queue_. |
472 mutable base::Lock incoming_queue_lock_; | 502 mutable base::Lock incoming_queue_lock_; |
473 | 503 |
474 RunState* state_; | 504 RunState* state_; |
475 | 505 |
476 #if defined(OS_WIN) | 506 #if defined(OS_WIN) |
477 base::TimeTicks high_resolution_timer_expiration_; | 507 base::TimeTicks high_resolution_timer_expiration_; |
478 #endif | 508 #endif |
479 | 509 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
600 #endif // defined(OS_POSIX) | 630 #endif // defined(OS_POSIX) |
601 }; | 631 }; |
602 | 632 |
603 // Do not add any member variables to MessageLoopForIO! This is important b/c | 633 // Do not add any member variables to MessageLoopForIO! This is important b/c |
604 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 634 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
605 // data that you need should be stored on the MessageLoop's pump_ instance. | 635 // data that you need should be stored on the MessageLoop's pump_ instance. |
606 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 636 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
607 MessageLoopForIO_should_not_have_extra_member_variables); | 637 MessageLoopForIO_should_not_have_extra_member_variables); |
608 | 638 |
609 #endif // BASE_MESSAGE_LOOP_H_ | 639 #endif // BASE_MESSAGE_LOOP_H_ |
OLD | NEW |