| 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_export.h" | 12 #include "base/base_export.h" |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/callback.h" | 14 #include "base/callback.h" |
| 15 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
| 17 #include "base/message_loop_proxy.h" | 17 #include "base/message_loop_proxy.h" |
| 18 #include "base/message_pump.h" | 18 #include "base/message_pump.h" |
| 19 #include "base/observer_list.h" | 19 #include "base/observer_list.h" |
| 20 #include "base/pending_task.h" |
| 20 #include "base/synchronization/lock.h" | 21 #include "base/synchronization/lock.h" |
| 21 #include "base/task.h" | 22 #include "base/task.h" |
| 22 #include "base/tracking_info.h" | 23 #include "base/tracking_info.h" |
| 23 #include "base/time.h" | 24 #include "base/time.h" |
| 24 | 25 |
| 25 #if defined(OS_WIN) | 26 #if defined(OS_WIN) |
| 26 // We need this to declare base::MessagePumpWin::Dispatcher, which we should | 27 // We need this to declare base::MessagePumpWin::Dispatcher, which we should |
| 27 // really just eliminate. | 28 // really just eliminate. |
| 28 #include "base/message_pump_win.h" | 29 #include "base/message_pump_win.h" |
| 29 #elif defined(OS_POSIX) | 30 #elif defined(OS_POSIX) |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 static MessageLoop* current(); | 119 static MessageLoop* current(); |
| 119 | 120 |
| 120 static void EnableHistogrammer(bool enable_histogrammer); | 121 static void EnableHistogrammer(bool enable_histogrammer); |
| 121 | 122 |
| 122 typedef base::MessagePump* (MessagePumpFactory)(); | 123 typedef base::MessagePump* (MessagePumpFactory)(); |
| 123 // Using the given base::MessagePumpForUIFactory to override the default | 124 // Using the given base::MessagePumpForUIFactory to override the default |
| 124 // MessagePump implementation for 'TYPE_UI'. | 125 // MessagePump implementation for 'TYPE_UI'. |
| 125 static void InitMessagePumpForUIFactory(MessagePumpFactory* factory); | 126 static void InitMessagePumpForUIFactory(MessagePumpFactory* factory); |
| 126 | 127 |
| 127 // A DestructionObserver is notified when the current MessageLoop is being | 128 // A DestructionObserver is notified when the current MessageLoop is being |
| 128 // destroyed. These obsevers are notified prior to MessageLoop::current() | 129 // destroyed. These observers are notified prior to MessageLoop::current() |
| 129 // being changed to return NULL. This gives interested parties the chance to | 130 // being changed to return NULL. This gives interested parties the chance to |
| 130 // do final cleanup that depends on the MessageLoop. | 131 // do final cleanup that depends on the MessageLoop. |
| 131 // | 132 // |
| 132 // NOTE: Any tasks posted to the MessageLoop during this notification will | 133 // NOTE: Any tasks posted to the MessageLoop during this notification will |
| 133 // not be run. Instead, they will be deleted. | 134 // not be run. Instead, they will be deleted. |
| 134 // | 135 // |
| 135 class BASE_EXPORT DestructionObserver { | 136 class BASE_EXPORT DestructionObserver { |
| 136 public: | 137 public: |
| 137 virtual void WillDestroyCurrentMessageLoop() = 0; | 138 virtual void WillDestroyCurrentMessageLoop() = 0; |
| 138 | 139 |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 explicit AutoRunState(MessageLoop* loop); | 405 explicit AutoRunState(MessageLoop* loop); |
| 405 ~AutoRunState(); | 406 ~AutoRunState(); |
| 406 private: | 407 private: |
| 407 MessageLoop* loop_; | 408 MessageLoop* loop_; |
| 408 RunState* previous_state_; | 409 RunState* previous_state_; |
| 409 }; | 410 }; |
| 410 #if defined(OS_ANDROID) | 411 #if defined(OS_ANDROID) |
| 411 protected: | 412 protected: |
| 412 #endif | 413 #endif |
| 413 | 414 |
| 414 // This structure is copied around by value. | |
| 415 struct PendingTask : public base::TrackingInfo { | |
| 416 PendingTask(const base::Closure& task, | |
| 417 const tracked_objects::Location& posted_from, | |
| 418 base::TimeTicks delayed_run_time, | |
| 419 bool nestable); | |
| 420 ~PendingTask(); | |
| 421 | |
| 422 // Used to support sorting. | |
| 423 bool operator<(const PendingTask& other) const; | |
| 424 | |
| 425 // The task to run. | |
| 426 base::Closure task; | |
| 427 | |
| 428 // The site this PendingTask was posted from. | |
| 429 tracked_objects::Location posted_from; | |
| 430 | |
| 431 // Secondary sort key for run time. | |
| 432 int sequence_num; | |
| 433 | |
| 434 // OK to dispatch from a nested loop. | |
| 435 bool nestable; | |
| 436 }; | |
| 437 | |
| 438 class TaskQueue : public std::queue<PendingTask> { | |
| 439 public: | |
| 440 void Swap(TaskQueue* queue) { | |
| 441 c.swap(queue->c); // Calls std::deque::swap | |
| 442 } | |
| 443 }; | |
| 444 | |
| 445 typedef std::priority_queue<PendingTask> DelayedTaskQueue; | |
| 446 | |
| 447 #if defined(OS_WIN) | 415 #if defined(OS_WIN) |
| 448 base::MessagePumpWin* pump_win() { | 416 base::MessagePumpWin* pump_win() { |
| 449 return static_cast<base::MessagePumpWin*>(pump_.get()); | 417 return static_cast<base::MessagePumpWin*>(pump_.get()); |
| 450 } | 418 } |
| 451 #elif defined(OS_POSIX) | 419 #elif defined(OS_POSIX) |
| 452 base::MessagePumpLibevent* pump_libevent() { | 420 base::MessagePumpLibevent* pump_libevent() { |
| 453 return static_cast<base::MessagePumpLibevent*>(pump_.get()); | 421 return static_cast<base::MessagePumpLibevent*>(pump_.get()); |
| 454 } | 422 } |
| 455 #endif | 423 #endif |
| 456 | 424 |
| 457 // A function to encapsulate all the exception handling capability in the | 425 // A function to encapsulate all the exception handling capability in the |
| 458 // stacks around the running of a main message loop. It will run the message | 426 // stacks around the running of a main message loop. It will run the message |
| 459 // loop in a SEH try block or not depending on the set_SEH_restoration() | 427 // loop in a SEH try block or not depending on the set_SEH_restoration() |
| 460 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). | 428 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). |
| 461 void RunHandler(); | 429 void RunHandler(); |
| 462 | 430 |
| 463 #if defined(OS_WIN) | 431 #if defined(OS_WIN) |
| 464 __declspec(noinline) void RunInternalInSEHFrame(); | 432 __declspec(noinline) void RunInternalInSEHFrame(); |
| 465 #endif | 433 #endif |
| 466 | 434 |
| 467 // A surrounding stack frame around the running of the message loop that | 435 // A surrounding stack frame around the running of the message loop that |
| 468 // supports all saving and restoring of state, as is needed for any/all (ugly) | 436 // supports all saving and restoring of state, as is needed for any/all (ugly) |
| 469 // recursive calls. | 437 // recursive calls. |
| 470 void RunInternal(); | 438 void RunInternal(); |
| 471 | 439 |
| 472 // Called to process any delayed non-nestable tasks. | 440 // Called to process any delayed non-nestable tasks. |
| 473 bool ProcessNextDelayedNonNestableTask(); | 441 bool ProcessNextDelayedNonNestableTask(); |
| 474 | 442 |
| 475 // Runs the specified PendingTask. | 443 // Runs the specified PendingTask. |
| 476 void RunTask(const PendingTask& pending_task); | 444 void RunTask(const base::PendingTask& pending_task); |
| 477 | 445 |
| 478 // Calls RunTask or queues the pending_task on the deferred task list if it | 446 // Calls RunTask or queues the pending_task on the deferred task list if it |
| 479 // cannot be run right now. Returns true if the task was run. | 447 // cannot be run right now. Returns true if the task was run. |
| 480 bool DeferOrRunPendingTask(const PendingTask& pending_task); | 448 bool DeferOrRunPendingTask(const base::PendingTask& pending_task); |
| 481 | 449 |
| 482 // Adds the pending task to delayed_work_queue_. | 450 // Adds the pending task to delayed_work_queue_. |
| 483 void AddToDelayedWorkQueue(const PendingTask& pending_task); | 451 void AddToDelayedWorkQueue(const base::PendingTask& pending_task); |
| 484 | 452 |
| 485 // Adds the pending task to our incoming_queue_. | 453 // Adds the pending task to our incoming_queue_. |
| 486 // | 454 // |
| 487 // Caller retains ownership of |pending_task|, but this function will | 455 // Caller retains ownership of |pending_task|, but this function will |
| 488 // reset the value of pending_task->task. This is needed to ensure | 456 // reset the value of pending_task->task. This is needed to ensure |
| 489 // that the posting call stack does not retain pending_task->task | 457 // that the posting call stack does not retain pending_task->task |
| 490 // beyond this function call. | 458 // beyond this function call. |
| 491 void AddToIncomingQueue(PendingTask* pending_task); | 459 void AddToIncomingQueue(base::PendingTask* pending_task); |
| 492 | 460 |
| 493 // Load tasks from the incoming_queue_ into work_queue_ if the latter is | 461 // Load tasks from the incoming_queue_ into work_queue_ if the latter is |
| 494 // empty. The former requires a lock to access, while the latter is directly | 462 // empty. The former requires a lock to access, while the latter is directly |
| 495 // accessible on this thread. | 463 // accessible on this thread. |
| 496 void ReloadWorkQueue(); | 464 void ReloadWorkQueue(); |
| 497 | 465 |
| 498 // Delete tasks that haven't run yet without running them. Used in the | 466 // Delete tasks that haven't run yet without running them. Used in the |
| 499 // destructor to make sure all the task's destructors get called. Returns | 467 // destructor to make sure all the task's destructors get called. Returns |
| 500 // true if some work was done. | 468 // true if some work was done. |
| 501 bool DeletePendingTasks(); | 469 bool DeletePendingTasks(); |
| 502 | 470 |
| 503 // Calcuates the time at which a PendingTask should run. | 471 // Calculates the time at which a PendingTask should run. |
| 504 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms); | 472 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms); |
| 505 | 473 |
| 506 // Start recording histogram info about events and action IF it was enabled | 474 // Start recording histogram info about events and action IF it was enabled |
| 507 // and IF the statistics recorder can accept a registration of our histogram. | 475 // and IF the statistics recorder can accept a registration of our histogram. |
| 508 void StartHistogrammer(); | 476 void StartHistogrammer(); |
| 509 | 477 |
| 510 // Add occurence of event to our histogram, so that we can see what is being | 478 // Add occurrence of event to our histogram, so that we can see what is being |
| 511 // done in a specific MessageLoop instance (i.e., specific thread). | 479 // done in a specific MessageLoop instance (i.e., specific thread). |
| 512 // If message_histogram_ is NULL, this is a no-op. | 480 // If message_histogram_ is NULL, this is a no-op. |
| 513 void HistogramEvent(int event); | 481 void HistogramEvent(int event); |
| 514 | 482 |
| 515 // base::MessagePump::Delegate methods: | 483 // base::MessagePump::Delegate methods: |
| 516 virtual bool DoWork(); | 484 virtual bool DoWork(); |
| 517 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time); | 485 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time); |
| 518 virtual bool DoIdleWork(); | 486 virtual bool DoIdleWork(); |
| 519 | 487 |
| 520 Type type_; | 488 Type type_; |
| 521 | 489 |
| 522 // A list of tasks that need to be processed by this instance. Note that | 490 // A list of tasks that need to be processed by this instance. Note that |
| 523 // this queue is only accessed (push/pop) by our current thread. | 491 // this queue is only accessed (push/pop) by our current thread. |
| 524 TaskQueue work_queue_; | 492 base::TaskQueue work_queue_; |
| 525 | 493 |
| 526 // Contains delayed tasks, sorted by their 'delayed_run_time' property. | 494 // Contains delayed tasks, sorted by their 'delayed_run_time' property. |
| 527 DelayedTaskQueue delayed_work_queue_; | 495 base::DelayedTaskQueue delayed_work_queue_; |
| 528 | 496 |
| 529 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. | 497 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. |
| 530 base::TimeTicks recent_time_; | 498 base::TimeTicks recent_time_; |
| 531 | 499 |
| 532 // A queue of non-nestable tasks that we had to defer because when it came | 500 // A queue of non-nestable tasks that we had to defer because when it came |
| 533 // time to execute them we were in a nested message loop. They will execute | 501 // time to execute them we were in a nested message loop. They will execute |
| 534 // once we're out of nested message loops. | 502 // once we're out of nested message loops. |
| 535 TaskQueue deferred_non_nestable_work_queue_; | 503 base::TaskQueue deferred_non_nestable_work_queue_; |
| 536 | 504 |
| 537 scoped_refptr<base::MessagePump> pump_; | 505 scoped_refptr<base::MessagePump> pump_; |
| 538 | 506 |
| 539 ObserverList<DestructionObserver> destruction_observers_; | 507 ObserverList<DestructionObserver> destruction_observers_; |
| 540 | 508 |
| 541 // A recursion block that prevents accidentally running additonal tasks when | 509 // A recursion block that prevents accidentally running additional tasks when |
| 542 // insider a (accidentally induced?) nested message pump. | 510 // insider a (accidentally induced?) nested message pump. |
| 543 bool nestable_tasks_allowed_; | 511 bool nestable_tasks_allowed_; |
| 544 | 512 |
| 545 bool exception_restoration_; | 513 bool exception_restoration_; |
| 546 | 514 |
| 547 std::string thread_name_; | 515 std::string thread_name_; |
| 548 // A profiling histogram showing the counts of various messages and events. | 516 // A profiling histogram showing the counts of various messages and events. |
| 549 base::Histogram* message_histogram_; | 517 base::Histogram* message_histogram_; |
| 550 | 518 |
| 551 // A null terminated list which creates an incoming_queue of tasks that are | 519 // A null terminated list which creates an incoming_queue of tasks that are |
| 552 // acquired under a mutex for processing on this instance's thread. These | 520 // acquired under a mutex for processing on this instance's thread. These |
| 553 // tasks have not yet been sorted out into items for our work_queue_ vs items | 521 // tasks have not yet been sorted out into items for our work_queue_ vs items |
| 554 // that will be handled by the TimerManager. | 522 // that will be handled by the TimerManager. |
| 555 TaskQueue incoming_queue_; | 523 base::TaskQueue incoming_queue_; |
| 556 // Protect access to incoming_queue_. | 524 // Protect access to incoming_queue_. |
| 557 mutable base::Lock incoming_queue_lock_; | 525 mutable base::Lock incoming_queue_lock_; |
| 558 | 526 |
| 559 RunState* state_; | 527 RunState* state_; |
| 560 | 528 |
| 561 // The need for this variable is subtle. Please see implementation comments | 529 // The need for this variable is subtle. Please see implementation comments |
| 562 // around where it is used. | 530 // around where it is used. |
| 563 bool should_leak_tasks_; | 531 bool should_leak_tasks_; |
| 564 | 532 |
| 565 #if defined(OS_WIN) | 533 #if defined(OS_WIN) |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 #endif // defined(OS_POSIX) | 670 #endif // defined(OS_POSIX) |
| 703 }; | 671 }; |
| 704 | 672 |
| 705 // Do not add any member variables to MessageLoopForIO! This is important b/c | 673 // Do not add any member variables to MessageLoopForIO! This is important b/c |
| 706 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 674 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
| 707 // data that you need should be stored on the MessageLoop's pump_ instance. | 675 // data that you need should be stored on the MessageLoop's pump_ instance. |
| 708 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 676 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
| 709 MessageLoopForIO_should_not_have_extra_member_variables); | 677 MessageLoopForIO_should_not_have_extra_member_variables); |
| 710 | 678 |
| 711 #endif // BASE_MESSAGE_LOOP_H_ | 679 #endif // BASE_MESSAGE_LOOP_H_ |
| OLD | NEW |