| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #include "base/message_loop/message_loop.h" | 5 #include "base/message_loop/message_loop.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/message_loop/message_pump_default.h" | 16 #include "base/message_loop/message_pump_default.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/metrics/statistics_recorder.h" | 18 #include "base/metrics/statistics_recorder.h" |
| 19 #include "base/run_loop.h" | 19 #include "base/run_loop.h" |
| 20 #include "base/stl_util.h" |
| 20 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 21 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 21 #include "base/thread_task_runner_handle.h" | 22 #include "base/thread_task_runner_handle.h" |
| 22 #include "base/threading/thread_local.h" | 23 #include "base/threading/thread_local.h" |
| 23 #include "base/time/time.h" | 24 #include "base/time/time.h" |
| 24 #include "base/trace_event/trace_event.h" | 25 #include "base/trace_event/trace_event.h" |
| 25 #include "base/tracked_objects.h" | 26 #include "base/tracked_objects.h" |
| 26 #include "build/build_config.h" | 27 #include "build/build_config.h" |
| 27 | 28 |
| 28 #if defined(OS_MACOSX) | 29 #if defined(OS_MACOSX) |
| 29 #include "base/message_loop/message_pump_mac.h" | 30 #include "base/message_loop/message_pump_mac.h" |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 pump_->Run(this); | 444 pump_->Run(this); |
| 444 } | 445 } |
| 445 | 446 |
| 446 bool MessageLoop::ProcessNextDelayedNonNestableTask() { | 447 bool MessageLoop::ProcessNextDelayedNonNestableTask() { |
| 447 if (run_loop_->run_depth_ != 1) | 448 if (run_loop_->run_depth_ != 1) |
| 448 return false; | 449 return false; |
| 449 | 450 |
| 450 if (deferred_non_nestable_work_queue_.empty()) | 451 if (deferred_non_nestable_work_queue_.empty()) |
| 451 return false; | 452 return false; |
| 452 | 453 |
| 453 PendingTask pending_task = deferred_non_nestable_work_queue_.front(); | 454 PendingTask pending_task = |
| 455 std::move(deferred_non_nestable_work_queue_.front()); |
| 454 deferred_non_nestable_work_queue_.pop(); | 456 deferred_non_nestable_work_queue_.pop(); |
| 455 | 457 |
| 456 RunTask(pending_task); | 458 RunTask(pending_task); |
| 457 return true; | 459 return true; |
| 458 } | 460 } |
| 459 | 461 |
| 460 void MessageLoop::RunTask(const PendingTask& pending_task) { | 462 void MessageLoop::RunTask(const PendingTask& pending_task) { |
| 461 DCHECK(nestable_tasks_allowed_); | 463 DCHECK(nestable_tasks_allowed_); |
| 462 | 464 |
| 463 #if defined(OS_WIN) | 465 #if defined(OS_WIN) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 476 | 478 |
| 477 FOR_EACH_OBSERVER(TaskObserver, task_observers_, | 479 FOR_EACH_OBSERVER(TaskObserver, task_observers_, |
| 478 WillProcessTask(pending_task)); | 480 WillProcessTask(pending_task)); |
| 479 task_annotator_.RunTask("MessageLoop::PostTask", pending_task); | 481 task_annotator_.RunTask("MessageLoop::PostTask", pending_task); |
| 480 FOR_EACH_OBSERVER(TaskObserver, task_observers_, | 482 FOR_EACH_OBSERVER(TaskObserver, task_observers_, |
| 481 DidProcessTask(pending_task)); | 483 DidProcessTask(pending_task)); |
| 482 | 484 |
| 483 nestable_tasks_allowed_ = true; | 485 nestable_tasks_allowed_ = true; |
| 484 } | 486 } |
| 485 | 487 |
| 486 bool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) { | 488 bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { |
| 487 if (pending_task.nestable || run_loop_->run_depth_ == 1) { | 489 if (pending_task.nestable || run_loop_->run_depth_ == 1) { |
| 488 RunTask(pending_task); | 490 RunTask(pending_task); |
| 489 // Show that we ran a task (Note: a new one might arrive as a | 491 // Show that we ran a task (Note: a new one might arrive as a |
| 490 // consequence!). | 492 // consequence!). |
| 491 return true; | 493 return true; |
| 492 } | 494 } |
| 493 | 495 |
| 494 // We couldn't run the task now because we're in a nested message loop | 496 // We couldn't run the task now because we're in a nested message loop |
| 495 // and the task isn't nestable. | 497 // and the task isn't nestable. |
| 496 deferred_non_nestable_work_queue_.push(pending_task); | 498 deferred_non_nestable_work_queue_.push(std::move(pending_task)); |
| 497 return false; | 499 return false; |
| 498 } | 500 } |
| 499 | 501 |
| 500 void MessageLoop::AddToDelayedWorkQueue(const PendingTask& pending_task) { | 502 void MessageLoop::AddToDelayedWorkQueue(PendingTask pending_task) { |
| 501 // Move to the delayed work queue. | 503 // Move to the delayed work queue. |
| 502 delayed_work_queue_.push(pending_task); | 504 delayed_work_queue_.push(std::move(pending_task)); |
| 503 } | 505 } |
| 504 | 506 |
| 505 bool MessageLoop::DeletePendingTasks() { | 507 bool MessageLoop::DeletePendingTasks() { |
| 506 bool did_work = !work_queue_.empty(); | 508 bool did_work = !work_queue_.empty(); |
| 507 while (!work_queue_.empty()) { | 509 while (!work_queue_.empty()) { |
| 508 PendingTask pending_task = work_queue_.front(); | 510 PendingTask pending_task = std::move(work_queue_.front()); |
| 509 work_queue_.pop(); | 511 work_queue_.pop(); |
| 510 if (!pending_task.delayed_run_time.is_null()) { | 512 if (!pending_task.delayed_run_time.is_null()) { |
| 511 // We want to delete delayed tasks in the same order in which they would | 513 // We want to delete delayed tasks in the same order in which they would |
| 512 // normally be deleted in case of any funny dependencies between delayed | 514 // normally be deleted in case of any funny dependencies between delayed |
| 513 // tasks. | 515 // tasks. |
| 514 AddToDelayedWorkQueue(pending_task); | 516 AddToDelayedWorkQueue(std::move(pending_task)); |
| 515 } | 517 } |
| 516 } | 518 } |
| 517 did_work |= !deferred_non_nestable_work_queue_.empty(); | 519 did_work |= !deferred_non_nestable_work_queue_.empty(); |
| 518 while (!deferred_non_nestable_work_queue_.empty()) { | 520 while (!deferred_non_nestable_work_queue_.empty()) { |
| 519 deferred_non_nestable_work_queue_.pop(); | 521 deferred_non_nestable_work_queue_.pop(); |
| 520 } | 522 } |
| 521 did_work |= !delayed_work_queue_.empty(); | 523 did_work |= !delayed_work_queue_.empty(); |
| 522 | 524 |
| 523 // Historically, we always delete the task regardless of valgrind status. It's | 525 // Historically, we always delete the task regardless of valgrind status. It's |
| 524 // not completely clear why we want to leak them in the loops above. This | 526 // not completely clear why we want to leak them in the loops above. This |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 return false; | 584 return false; |
| 583 } | 585 } |
| 584 | 586 |
| 585 for (;;) { | 587 for (;;) { |
| 586 ReloadWorkQueue(); | 588 ReloadWorkQueue(); |
| 587 if (work_queue_.empty()) | 589 if (work_queue_.empty()) |
| 588 break; | 590 break; |
| 589 | 591 |
| 590 // Execute oldest task. | 592 // Execute oldest task. |
| 591 do { | 593 do { |
| 592 PendingTask pending_task = work_queue_.front(); | 594 PendingTask pending_task = std::move(work_queue_.front()); |
| 593 work_queue_.pop(); | 595 work_queue_.pop(); |
| 594 if (!pending_task.delayed_run_time.is_null()) { | 596 if (!pending_task.delayed_run_time.is_null()) { |
| 595 AddToDelayedWorkQueue(pending_task); | 597 int sequence_num = pending_task.sequence_num; |
| 598 TimeTicks delayed_run_time = pending_task.delayed_run_time; |
| 599 AddToDelayedWorkQueue(std::move(pending_task)); |
| 596 // If we changed the topmost task, then it is time to reschedule. | 600 // If we changed the topmost task, then it is time to reschedule. |
| 597 if (delayed_work_queue_.top().task.Equals(pending_task.task)) | 601 if (delayed_work_queue_.top().sequence_num != sequence_num) |
| 598 pump_->ScheduleDelayedWork(pending_task.delayed_run_time); | 602 pump_->ScheduleDelayedWork(delayed_run_time); |
| 599 } else { | 603 } else { |
| 600 if (DeferOrRunPendingTask(pending_task)) | 604 if (DeferOrRunPendingTask(std::move(pending_task))) |
| 601 return true; | 605 return true; |
| 602 } | 606 } |
| 603 } while (!work_queue_.empty()); | 607 } while (!work_queue_.empty()); |
| 604 } | 608 } |
| 605 | 609 |
| 606 // Nothing happened. | 610 // Nothing happened. |
| 607 return false; | 611 return false; |
| 608 } | 612 } |
| 609 | 613 |
| 610 bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { | 614 bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 622 | 626 |
| 623 TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time; | 627 TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time; |
| 624 if (next_run_time > recent_time_) { | 628 if (next_run_time > recent_time_) { |
| 625 recent_time_ = TimeTicks::Now(); // Get a better view of Now(); | 629 recent_time_ = TimeTicks::Now(); // Get a better view of Now(); |
| 626 if (next_run_time > recent_time_) { | 630 if (next_run_time > recent_time_) { |
| 627 *next_delayed_work_time = next_run_time; | 631 *next_delayed_work_time = next_run_time; |
| 628 return false; | 632 return false; |
| 629 } | 633 } |
| 630 } | 634 } |
| 631 | 635 |
| 632 PendingTask pending_task = delayed_work_queue_.top(); | 636 PendingTask pending_task = PopOutFromPriorityQueue(&delayed_work_queue_); |
| 633 delayed_work_queue_.pop(); | |
| 634 | 637 |
| 635 if (!delayed_work_queue_.empty()) | 638 if (!delayed_work_queue_.empty()) |
| 636 *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; | 639 *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; |
| 637 | 640 |
| 638 return DeferOrRunPendingTask(pending_task); | 641 return DeferOrRunPendingTask(std::move(pending_task)); |
| 639 } | 642 } |
| 640 | 643 |
| 641 bool MessageLoop::DoIdleWork() { | 644 bool MessageLoop::DoIdleWork() { |
| 642 if (ProcessNextDelayedNonNestableTask()) | 645 if (ProcessNextDelayedNonNestableTask()) |
| 643 return true; | 646 return true; |
| 644 | 647 |
| 645 if (run_loop_->quit_when_idle_received_) | 648 if (run_loop_->quit_when_idle_received_) |
| 646 pump_->Quit(); | 649 pump_->Quit(); |
| 647 | 650 |
| 648 // When we return we will do a kernel wait for more tasks. | 651 // When we return we will do a kernel wait for more tasks. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 persistent, | 751 persistent, |
| 749 mode, | 752 mode, |
| 750 controller, | 753 controller, |
| 751 delegate); | 754 delegate); |
| 752 } | 755 } |
| 753 #endif | 756 #endif |
| 754 | 757 |
| 755 #endif // !defined(OS_NACL_SFI) | 758 #endif // !defined(OS_NACL_SFI) |
| 756 | 759 |
| 757 } // namespace base | 760 } // namespace base |
| OLD | NEW |