Chromium Code Reviews| 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 26 matching lines...) Expand all Loading... | |
| 37 | 37 |
| 38 namespace base { | 38 namespace base { |
| 39 | 39 |
| 40 namespace { | 40 namespace { |
| 41 | 41 |
| 42 // A lazily created thread local storage for quick access to a thread's message | 42 // A lazily created thread local storage for quick access to a thread's message |
| 43 // loop, if one exists. This should be safe and free of static constructors. | 43 // loop, if one exists. This should be safe and free of static constructors. |
| 44 LazyInstance<base::ThreadLocalPointer<MessageLoop> >::Leaky lazy_tls_ptr = | 44 LazyInstance<base::ThreadLocalPointer<MessageLoop> >::Leaky lazy_tls_ptr = |
| 45 LAZY_INSTANCE_INITIALIZER; | 45 LAZY_INSTANCE_INITIALIZER; |
| 46 | 46 |
| 47 // Logical events for Histogram profiling. Run with -message-loop-histogrammer | 47 // Logical events for Histogram profiling. Run with --message-loop-histogrammer |
| 48 // to get an accounting of messages and actions taken on each thread. | 48 // to get an accounting of messages and actions taken on each thread. |
| 49 const int kTaskRunEvent = 0x1; | 49 const int kTaskRunEvent = 0x1; |
| 50 #if !defined(OS_NACL) | 50 #if !defined(OS_NACL) |
| 51 const int kTimerEvent = 0x2; | 51 const int kTimerEvent = 0x2; |
| 52 | 52 |
| 53 // Provide range of message IDs for use in histogramming and debug display. | 53 // Provide range of message IDs for use in histogramming and debug display. |
| 54 const int kLeastNonZeroMessageId = 1; | 54 const int kLeastNonZeroMessageId = 1; |
| 55 const int kMaxMessageId = 1099; | 55 const int kMaxMessageId = 1099; |
| 56 const int kNumberOfDistinctMessagesDisplayed = 1100; | 56 const int kNumberOfDistinctMessagesDisplayed = 1100; |
| 57 | 57 |
| 58 // Provide a macro that takes an expression (such as a constant, or macro | 58 // Provide a macro that takes an expression (such as a constant, or macro |
| 59 // constant) and creates a pair to initalize an array of pairs. In this case, | 59 // constant) and creates a pair to initialize an array of pairs. In this case, |
| 60 // our pair consists of the expressions value, and the "stringized" version | 60 // our pair consists of the expressions value, and the "stringized" version |
| 61 // of the expression (i.e., the exrpression put in quotes). For example, if | 61 // of the expression (i.e., the expression put in quotes). For example, if |
| 62 // we have: | 62 // we have: |
| 63 // #define FOO 2 | 63 // #define FOO 2 |
| 64 // #define BAR 5 | 64 // #define BAR 5 |
| 65 // then the following: | 65 // then the following: |
| 66 // VALUE_TO_NUMBER_AND_NAME(FOO + BAR) | 66 // VALUE_TO_NUMBER_AND_NAME(FOO + BAR) |
| 67 // will expand to: | 67 // will expand to: |
| 68 // {7, "FOO + BAR"} | 68 // {7, "FOO + BAR"} |
| 69 // We use the resulting array as an argument to our histogram, which reads the | 69 // We use the resulting array as an argument to our histogram, which reads the |
| 70 // number as a bucket identifier, and proceeds to use the corresponding name | 70 // number as a bucket identifier, and proceeds to use the corresponding name |
| 71 // in the pair (i.e., the quoted string) when printing out a histogram. | 71 // in the pair (i.e., the quoted string) when printing out a histogram. |
| 72 #define VALUE_TO_NUMBER_AND_NAME(name) {name, #name}, | 72 #define VALUE_TO_NUMBER_AND_NAME(name) {name, #name}, |
| 73 | 73 |
| 74 const LinearHistogram::DescriptionPair event_descriptions_[] = { | 74 const LinearHistogram::DescriptionPair event_descriptions_[] = { |
| 75 // Provide some pretty print capability in our histogram for our internal | 75 // Provide some pretty print capability in our histogram for our internal |
| 76 // messages. | 76 // messages. |
| 77 | 77 |
| 78 // A few events we handle (kindred to messages), and used to profile actions. | 78 // A few events we handle (kindred to messages), and used to profile actions. |
| 79 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) | 79 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) |
| 80 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) | 80 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) |
| 81 | 81 |
| 82 {-1, NULL} // The list must be null terminated, per API to histogram. | 82 {-1, NULL} // The list must be null-terminated, per API to histogram. |
| 83 }; | 83 }; |
| 84 #endif // !defined(OS_NACL) | 84 #endif // !defined(OS_NACL) |
| 85 | 85 |
| 86 bool enable_histogrammer_ = false; | 86 bool enable_histogrammer_ = false; |
| 87 | 87 |
| 88 MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL; | 88 MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL; |
| 89 | 89 |
| 90 #if defined(OS_IOS) | 90 #if defined(OS_IOS) |
| 91 typedef MessagePumpIOSForIO MessagePumpForIO; | 91 typedef MessagePumpIOSForIO MessagePumpForIO; |
| 92 #elif defined(OS_NACL_SFI) | 92 #elif defined(OS_NACL_SFI) |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 bool MessageLoop::is_running() const { | 355 bool MessageLoop::is_running() const { |
| 356 DCHECK_EQ(this, current()); | 356 DCHECK_EQ(this, current()); |
| 357 return run_loop_ != NULL; | 357 return run_loop_ != NULL; |
| 358 } | 358 } |
| 359 | 359 |
| 360 bool MessageLoop::HasHighResolutionTasks() { | 360 bool MessageLoop::HasHighResolutionTasks() { |
| 361 return incoming_task_queue_->HasHighResolutionTasks(); | 361 return incoming_task_queue_->HasHighResolutionTasks(); |
| 362 } | 362 } |
| 363 | 363 |
| 364 bool MessageLoop::IsIdleForTesting() { | 364 bool MessageLoop::IsIdleForTesting() { |
| 365 // We only check the imcoming queue|, since we don't want to lock the work | 365 // We only check the imcoming queue, since we don't want to lock the work |
|
Lei Zhang
2015/07/24 01:39:51
typo "imcoming"
qyearsley
2015/07/24 02:18:42
Good catch
| |
| 366 // queue. | 366 // queue. |
| 367 return incoming_task_queue_->IsIdleForTesting(); | 367 return incoming_task_queue_->IsIdleForTesting(); |
| 368 } | 368 } |
| 369 | 369 |
| 370 //------------------------------------------------------------------------------ | 370 //------------------------------------------------------------------------------ |
| 371 | 371 |
| 372 // static | 372 // static |
| 373 scoped_ptr<MessageLoop> MessageLoop::CreateUnbound( | 373 scoped_ptr<MessageLoop> MessageLoop::CreateUnbound( |
| 374 Type type, MessagePumpFactoryCallback pump_factory) { | 374 Type type, MessagePumpFactoryCallback pump_factory) { |
| 375 return make_scoped_ptr(new MessageLoop(type, pump_factory)); | 375 return make_scoped_ptr(new MessageLoop(type, pump_factory)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 scoped_refptr<SingleThreadTaskRunner> task_runner) { | 416 scoped_refptr<SingleThreadTaskRunner> task_runner) { |
| 417 DCHECK_EQ(this, current()); | 417 DCHECK_EQ(this, current()); |
| 418 DCHECK(task_runner->BelongsToCurrentThread()); | 418 DCHECK(task_runner->BelongsToCurrentThread()); |
| 419 DCHECK(!unbound_task_runner_); | 419 DCHECK(!unbound_task_runner_); |
| 420 task_runner_ = task_runner.Pass(); | 420 task_runner_ = task_runner.Pass(); |
| 421 SetThreadTaskRunnerHandle(); | 421 SetThreadTaskRunnerHandle(); |
| 422 } | 422 } |
| 423 | 423 |
| 424 void MessageLoop::SetThreadTaskRunnerHandle() { | 424 void MessageLoop::SetThreadTaskRunnerHandle() { |
| 425 DCHECK_EQ(this, current()); | 425 DCHECK_EQ(this, current()); |
| 426 // Clear the previous thread task runner first because only one can exist at | 426 // Clear the previous thread task runner first, because only one can exist at |
| 427 // a time. | 427 // a time. |
| 428 thread_task_runner_handle_.reset(); | 428 thread_task_runner_handle_.reset(); |
| 429 thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_)); | 429 thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_)); |
| 430 } | 430 } |
| 431 | 431 |
| 432 void MessageLoop::RunHandler() { | 432 void MessageLoop::RunHandler() { |
| 433 DCHECK_EQ(this, current()); | 433 DCHECK_EQ(this, current()); |
| 434 | 434 |
| 435 StartHistogrammer(); | 435 StartHistogrammer(); |
| 436 | 436 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 608 // Nothing happened. | 608 // Nothing happened. |
| 609 return false; | 609 return false; |
| 610 } | 610 } |
| 611 | 611 |
| 612 bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { | 612 bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { |
| 613 if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { | 613 if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { |
| 614 recent_time_ = *next_delayed_work_time = TimeTicks(); | 614 recent_time_ = *next_delayed_work_time = TimeTicks(); |
| 615 return false; | 615 return false; |
| 616 } | 616 } |
| 617 | 617 |
| 618 // When we "fall behind," there will be a lot of tasks in the delayed work | 618 // When we "fall behind", there will be a lot of tasks in the delayed work |
| 619 // queue that are ready to run. To increase efficiency when we fall behind, | 619 // queue that are ready to run. To increase efficiency when we fall behind, |
| 620 // we will only call Time::Now() intermittently, and then process all tasks | 620 // we will only call Time::Now() intermittently, and then process all tasks |
| 621 // that are ready to run before calling it again. As a result, the more we | 621 // that are ready to run before calling it again. As a result, the more we |
| 622 // fall behind (and have a lot of ready-to-run delayed tasks), the more | 622 // fall behind (and have a lot of ready-to-run delayed tasks), the more |
| 623 // efficient we'll be at handling the tasks. | 623 // efficient we'll be at handling the tasks. |
| 624 | 624 |
| 625 TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time; | 625 TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time; |
| 626 if (next_run_time > recent_time_) { | 626 if (next_run_time > recent_time_) { |
| 627 recent_time_ = TimeTicks::Now(); // Get a better view of Now(); | 627 recent_time_ = TimeTicks::Now(); // Get a better view of Now(); |
| 628 if (next_run_time > recent_time_) { | 628 if (next_run_time > recent_time_) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 747 persistent, | 747 persistent, |
| 748 mode, | 748 mode, |
| 749 controller, | 749 controller, |
| 750 delegate); | 750 delegate); |
| 751 } | 751 } |
| 752 #endif | 752 #endif |
| 753 | 753 |
| 754 #endif // !defined(OS_NACL_SFI) | 754 #endif // !defined(OS_NACL_SFI) |
| 755 | 755 |
| 756 } // namespace base | 756 } // namespace base |
| OLD | NEW |