| 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 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 MessageLoop::TaskObserver::~TaskObserver() { | 120 MessageLoop::TaskObserver::~TaskObserver() { |
| 121 } | 121 } |
| 122 | 122 |
| 123 MessageLoop::DestructionObserver::~DestructionObserver() { | 123 MessageLoop::DestructionObserver::~DestructionObserver() { |
| 124 } | 124 } |
| 125 | 125 |
| 126 //------------------------------------------------------------------------------ | 126 //------------------------------------------------------------------------------ |
| 127 | 127 |
| 128 MessageLoop::MessageLoop(Type type) | 128 MessageLoop::MessageLoop(Type type) |
| 129 : type_(type), | 129 : type_(type), |
| 130 pending_high_res_tasks_(0), |
| 131 in_high_res_mode_(false), |
| 130 nestable_tasks_allowed_(true), | 132 nestable_tasks_allowed_(true), |
| 131 #if defined(OS_WIN) | 133 #if defined(OS_WIN) |
| 132 os_modal_loop_(false), | 134 os_modal_loop_(false), |
| 133 #endif // OS_WIN | 135 #endif // OS_WIN |
| 134 message_histogram_(NULL), | 136 message_histogram_(NULL), |
| 135 run_loop_(NULL) { | 137 run_loop_(NULL) { |
| 136 Init(); | 138 Init(); |
| 137 | 139 |
| 138 pump_ = CreateMessagePumpForType(type).Pass(); | 140 pump_ = CreateMessagePumpForType(type).Pass(); |
| 139 } | 141 } |
| 140 | 142 |
| 141 MessageLoop::MessageLoop(scoped_ptr<MessagePump> pump) | 143 MessageLoop::MessageLoop(scoped_ptr<MessagePump> pump) |
| 142 : pump_(pump.Pass()), | 144 : pump_(pump.Pass()), |
| 143 type_(TYPE_CUSTOM), | 145 type_(TYPE_CUSTOM), |
| 146 pending_high_res_tasks_(0), |
| 147 in_high_res_mode_(false), |
| 144 nestable_tasks_allowed_(true), | 148 nestable_tasks_allowed_(true), |
| 145 #if defined(OS_WIN) | 149 #if defined(OS_WIN) |
| 146 os_modal_loop_(false), | 150 os_modal_loop_(false), |
| 147 #endif // OS_WIN | 151 #endif // OS_WIN |
| 148 message_histogram_(NULL), | 152 message_histogram_(NULL), |
| 149 run_loop_(NULL) { | 153 run_loop_(NULL) { |
| 150 DCHECK(pump_.get()); | 154 DCHECK(pump_.get()); |
| 151 Init(); | 155 Init(); |
| 152 } | 156 } |
| 153 | 157 |
| 154 MessageLoop::~MessageLoop() { | 158 MessageLoop::~MessageLoop() { |
| 155 DCHECK_EQ(this, current()); | 159 DCHECK_EQ(this, current()); |
| 156 | 160 |
| 157 DCHECK(!run_loop_); | 161 DCHECK(!run_loop_); |
| 158 | 162 #if defined(OS_WIN) |
| 163 if (in_high_res_mode_) |
| 164 Time::ActivateHighResolutionTimer(false); |
| 165 #endif |
| 159 // Clean up any unprocessed tasks, but take care: deleting a task could | 166 // Clean up any unprocessed tasks, but take care: deleting a task could |
| 160 // result in the addition of more tasks (e.g., via DeleteSoon). We set a | 167 // result in the addition of more tasks (e.g., via DeleteSoon). We set a |
| 161 // limit on the number of times we will allow a deleted task to generate more | 168 // limit on the number of times we will allow a deleted task to generate more |
| 162 // tasks. Normally, we should only pass through this loop once or twice. If | 169 // tasks. Normally, we should only pass through this loop once or twice. If |
| 163 // we end up hitting the loop limit, then it is probably due to one task that | 170 // we end up hitting the loop limit, then it is probably due to one task that |
| 164 // is being stubborn. Inspect the queues to see who is left. | 171 // is being stubborn. Inspect the queues to see who is left. |
| 165 bool did_work; | 172 bool did_work; |
| 166 for (int i = 0; i < 100; ++i) { | 173 for (int i = 0; i < 100; ++i) { |
| 167 DeletePendingTasks(); | 174 DeletePendingTasks(); |
| 168 ReloadWorkQueue(); | 175 ReloadWorkQueue(); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { | 369 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { |
| 363 DCHECK_EQ(this, current()); | 370 DCHECK_EQ(this, current()); |
| 364 task_observers_.RemoveObserver(task_observer); | 371 task_observers_.RemoveObserver(task_observer); |
| 365 } | 372 } |
| 366 | 373 |
| 367 bool MessageLoop::is_running() const { | 374 bool MessageLoop::is_running() const { |
| 368 DCHECK_EQ(this, current()); | 375 DCHECK_EQ(this, current()); |
| 369 return run_loop_ != NULL; | 376 return run_loop_ != NULL; |
| 370 } | 377 } |
| 371 | 378 |
| 372 bool MessageLoop::IsHighResolutionTimerEnabledForTesting() { | 379 bool MessageLoop::HasHighResolutionTasks() { |
| 373 return incoming_task_queue_->IsHighResolutionTimerEnabledForTesting(); | 380 return incoming_task_queue_->HasHighResolutionTasks(); |
| 374 } | 381 } |
| 375 | 382 |
| 376 bool MessageLoop::IsIdleForTesting() { | 383 bool MessageLoop::IsIdleForTesting() { |
| 377 // We only check the imcoming queue|, since we don't want to lock the work | 384 // We only check the imcoming queue|, since we don't want to lock the work |
| 378 // queue. | 385 // queue. |
| 379 return incoming_task_queue_->IsIdleForTesting(); | 386 return incoming_task_queue_->IsIdleForTesting(); |
| 380 } | 387 } |
| 381 | 388 |
| 382 //------------------------------------------------------------------------------ | 389 //------------------------------------------------------------------------------ |
| 383 | 390 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 PendingTask pending_task = deferred_non_nestable_work_queue_.front(); | 425 PendingTask pending_task = deferred_non_nestable_work_queue_.front(); |
| 419 deferred_non_nestable_work_queue_.pop(); | 426 deferred_non_nestable_work_queue_.pop(); |
| 420 | 427 |
| 421 RunTask(pending_task); | 428 RunTask(pending_task); |
| 422 return true; | 429 return true; |
| 423 } | 430 } |
| 424 | 431 |
| 425 void MessageLoop::RunTask(const PendingTask& pending_task) { | 432 void MessageLoop::RunTask(const PendingTask& pending_task) { |
| 426 DCHECK(nestable_tasks_allowed_); | 433 DCHECK(nestable_tasks_allowed_); |
| 427 | 434 |
| 435 if (pending_task.is_high_res) { |
| 436 pending_high_res_tasks_--; |
| 437 CHECK(pending_high_res_tasks_ >= 0); |
| 438 } |
| 428 // Execute the task and assume the worst: It is probably not reentrant. | 439 // Execute the task and assume the worst: It is probably not reentrant. |
| 429 nestable_tasks_allowed_ = false; | 440 nestable_tasks_allowed_ = false; |
| 430 | 441 |
| 431 HistogramEvent(kTaskRunEvent); | 442 HistogramEvent(kTaskRunEvent); |
| 432 | 443 |
| 433 FOR_EACH_OBSERVER(TaskObserver, task_observers_, | 444 FOR_EACH_OBSERVER(TaskObserver, task_observers_, |
| 434 WillProcessTask(pending_task)); | 445 WillProcessTask(pending_task)); |
| 435 task_annotator_.RunTask( | 446 task_annotator_.RunTask( |
| 436 "MessageLoop::PostTask", "MessageLoop::RunTask", pending_task); | 447 "MessageLoop::PostTask", "MessageLoop::RunTask", pending_task); |
| 437 FOR_EACH_OBSERVER(TaskObserver, task_observers_, | 448 FOR_EACH_OBSERVER(TaskObserver, task_observers_, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 delayed_work_queue_.pop(); | 497 delayed_work_queue_.pop(); |
| 487 } | 498 } |
| 488 return did_work; | 499 return did_work; |
| 489 } | 500 } |
| 490 | 501 |
| 491 void MessageLoop::ReloadWorkQueue() { | 502 void MessageLoop::ReloadWorkQueue() { |
| 492 // We can improve performance of our loading tasks from the incoming queue to | 503 // We can improve performance of our loading tasks from the incoming queue to |
| 493 // |*work_queue| by waiting until the last minute (|*work_queue| is empty) to | 504 // |*work_queue| by waiting until the last minute (|*work_queue| is empty) to |
| 494 // load. That reduces the number of locks-per-task significantly when our | 505 // load. That reduces the number of locks-per-task significantly when our |
| 495 // queues get large. | 506 // queues get large. |
| 496 if (work_queue_.empty()) | 507 if (work_queue_.empty()) { |
| 497 incoming_task_queue_->ReloadWorkQueue(&work_queue_); | 508 pending_high_res_tasks_ += |
| 509 incoming_task_queue_->ReloadWorkQueue(&work_queue_); |
| 510 } |
| 498 } | 511 } |
| 499 | 512 |
| 500 void MessageLoop::ScheduleWork(bool was_empty) { | 513 void MessageLoop::ScheduleWork(bool was_empty) { |
| 501 if (was_empty || AlwaysNotifyPump(type_)) | 514 if (was_empty || AlwaysNotifyPump(type_)) |
| 502 pump_->ScheduleWork(); | 515 pump_->ScheduleWork(); |
| 503 } | 516 } |
| 504 | 517 |
| 505 //------------------------------------------------------------------------------ | 518 //------------------------------------------------------------------------------ |
| 506 // Method and data for histogramming events and actions taken by each instance | 519 // Method and data for histogramming events and actions taken by each instance |
| 507 // on each thread. | 520 // on each thread. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 return DeferOrRunPendingTask(pending_task); | 603 return DeferOrRunPendingTask(pending_task); |
| 591 } | 604 } |
| 592 | 605 |
| 593 bool MessageLoop::DoIdleWork() { | 606 bool MessageLoop::DoIdleWork() { |
| 594 if (ProcessNextDelayedNonNestableTask()) | 607 if (ProcessNextDelayedNonNestableTask()) |
| 595 return true; | 608 return true; |
| 596 | 609 |
| 597 if (run_loop_->quit_when_idle_received_) | 610 if (run_loop_->quit_when_idle_received_) |
| 598 pump_->Quit(); | 611 pump_->Quit(); |
| 599 | 612 |
| 613 // When we return we will do a kernel wait for more tasks. |
| 614 #if defined(OS_WIN) |
| 615 // On Windows we activate the high resolution timer so that the wait |
| 616 // _if_ triggered by the timer happens with good resolution. If we don't |
| 617 // do this the default resolution is 15ms which might not be acceptable |
| 618 // for some tasks. |
| 619 in_high_res_mode_ = pending_high_res_tasks_ > 0; |
| 620 Time::ActivateHighResolutionTimer(in_high_res_mode_); |
| 621 #endif |
| 600 return false; | 622 return false; |
| 601 } | 623 } |
| 602 | 624 |
| 603 void MessageLoop::DeleteSoonInternal(const tracked_objects::Location& from_here, | 625 void MessageLoop::DeleteSoonInternal(const tracked_objects::Location& from_here, |
| 604 void(*deleter)(const void*), | 626 void(*deleter)(const void*), |
| 605 const void* object) { | 627 const void* object) { |
| 606 PostNonNestableTask(from_here, Bind(deleter, object)); | 628 PostNonNestableTask(from_here, Bind(deleter, object)); |
| 607 } | 629 } |
| 608 | 630 |
| 609 void MessageLoop::ReleaseSoonInternal( | 631 void MessageLoop::ReleaseSoonInternal( |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 persistent, | 707 persistent, |
| 686 mode, | 708 mode, |
| 687 controller, | 709 controller, |
| 688 delegate); | 710 delegate); |
| 689 } | 711 } |
| 690 #endif | 712 #endif |
| 691 | 713 |
| 692 #endif // !defined(OS_NACL) | 714 #endif // !defined(OS_NACL) |
| 693 | 715 |
| 694 } // namespace base | 716 } // namespace base |
| OLD | NEW |