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 incoming queue, since we don't want to lock the work |
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 |