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/incoming_task_queue.h" | 5 #include "base/message_loop/incoming_task_queue.h" |
6 | 6 |
7 #include "base/location.h" | 7 #include "base/location.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/metrics/histogram.h" | |
9 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" |
10 #include "base/time/time.h" | 11 #include "base/time/time.h" |
11 | 12 |
12 namespace base { | 13 namespace base { |
13 namespace internal { | 14 namespace internal { |
14 | 15 |
16 namespace { | |
17 // Returns true if MessagePump::ScheduleWork() must be called one | |
rvargas (doing something else)
2014/11/17 19:18:50
nit: add empty line here.
| |
18 // time for every task that is added to the MessageLoop incoming queue. | |
19 bool AlwaysNotifyPump(MessageLoop::Type type) { | |
20 #if defined(OS_ANDROID) | |
21 // The Android UI message loop needs to get notified each time a task is | |
22 // added | |
23 // to the incoming queue. | |
24 return type == MessageLoop::TYPE_UI || type == MessageLoop::TYPE_JAVA; | |
25 #else | |
26 return false; | |
27 #endif | |
28 } | |
29 } | |
rvargas (doing something else)
2014/11/17 19:18:49
nit: add empty line and " // namespace"
| |
30 | |
15 IncomingTaskQueue::IncomingTaskQueue(MessageLoop* message_loop) | 31 IncomingTaskQueue::IncomingTaskQueue(MessageLoop* message_loop) |
16 : high_res_task_count_(0), | 32 : high_res_task_count_(0), |
17 message_loop_(message_loop), | 33 message_loop_(message_loop), |
18 next_sequence_num_(0) { | 34 next_sequence_num_(0), |
35 message_loop_scheduled_(false), | |
36 always_schedule_work_(AlwaysNotifyPump(message_loop_->type())) { | |
19 } | 37 } |
20 | 38 |
21 bool IncomingTaskQueue::AddToIncomingQueue( | 39 bool IncomingTaskQueue::AddToIncomingQueue( |
22 const tracked_objects::Location& from_here, | 40 const tracked_objects::Location& from_here, |
23 const Closure& task, | 41 const Closure& task, |
24 TimeDelta delay, | 42 TimeDelta delay, |
25 bool nestable) { | 43 bool nestable) { |
26 AutoLock locked(incoming_queue_lock_); | 44 AutoLock locked(incoming_queue_lock_); |
27 PendingTask pending_task( | 45 PendingTask pending_task( |
28 from_here, task, CalculateDelayedRuntime(delay), nestable); | 46 from_here, task, CalculateDelayedRuntime(delay), nestable); |
(...skipping 20 matching lines...) Expand all Loading... | |
49 AutoLock lock(incoming_queue_lock_); | 67 AutoLock lock(incoming_queue_lock_); |
50 return incoming_queue_.empty(); | 68 return incoming_queue_.empty(); |
51 } | 69 } |
52 | 70 |
53 int IncomingTaskQueue::ReloadWorkQueue(TaskQueue* work_queue) { | 71 int IncomingTaskQueue::ReloadWorkQueue(TaskQueue* work_queue) { |
54 // Make sure no tasks are lost. | 72 // Make sure no tasks are lost. |
55 DCHECK(work_queue->empty()); | 73 DCHECK(work_queue->empty()); |
56 | 74 |
57 // Acquire all we can from the inter-thread queue with one lock acquisition. | 75 // Acquire all we can from the inter-thread queue with one lock acquisition. |
58 AutoLock lock(incoming_queue_lock_); | 76 AutoLock lock(incoming_queue_lock_); |
59 if (!incoming_queue_.empty()) | 77 if (!incoming_queue_.empty()) { |
rvargas (doing something else)
2014/11/17 19:18:49
nit: invert the order of the if.
| |
60 incoming_queue_.Swap(work_queue); | 78 incoming_queue_.Swap(work_queue); |
61 | 79 } else { |
80 // If the loop attempts to reload but there are no tasks in the incoming | |
rvargas (doing something else)
2014/11/17 19:18:49
Having to assume what the owner class will do is n
| |
81 // queue, that means it will go to sleep waiting for more work. If the | |
82 // incoming queue becomes nonempty we need to schedule it again. | |
83 message_loop_scheduled_ = false; | |
84 } | |
62 // Reset the count of high resolution tasks since our queue is now empty. | 85 // Reset the count of high resolution tasks since our queue is now empty. |
63 int high_res_tasks = high_res_task_count_; | 86 int high_res_tasks = high_res_task_count_; |
64 high_res_task_count_ = 0; | 87 high_res_task_count_ = 0; |
65 return high_res_tasks; | 88 return high_res_tasks; |
66 } | 89 } |
67 | 90 |
68 void IncomingTaskQueue::WillDestroyCurrentMessageLoop() { | 91 void IncomingTaskQueue::WillDestroyCurrentMessageLoop() { |
69 AutoLock lock(incoming_queue_lock_); | 92 AutoLock lock(incoming_queue_lock_); |
70 message_loop_ = NULL; | 93 message_loop_ = NULL; |
71 } | 94 } |
(...skipping 30 matching lines...) Expand all Loading... | |
102 // delayed_run_time value) and for identifying the task in about:tracing. | 125 // delayed_run_time value) and for identifying the task in about:tracing. |
103 pending_task->sequence_num = next_sequence_num_++; | 126 pending_task->sequence_num = next_sequence_num_++; |
104 | 127 |
105 message_loop_->task_annotator()->DidQueueTask("MessageLoop::PostTask", | 128 message_loop_->task_annotator()->DidQueueTask("MessageLoop::PostTask", |
106 *pending_task); | 129 *pending_task); |
107 | 130 |
108 bool was_empty = incoming_queue_.empty(); | 131 bool was_empty = incoming_queue_.empty(); |
109 incoming_queue_.push(*pending_task); | 132 incoming_queue_.push(*pending_task); |
110 pending_task->task.Reset(); | 133 pending_task->task.Reset(); |
111 | 134 |
112 // Wake up the pump. | 135 if (!message_loop_scheduled_ && (was_empty || always_schedule_work_)) { |
113 message_loop_->ScheduleWork(was_empty); | 136 // Wake up the message loop. |
137 message_loop_->ScheduleWork(); | |
138 // After we've scheduled the message loop, we do not need to do so again | |
139 // until we know it has processed all of the work in our queue and is | |
140 // waiting for more work again. The message loop will always attempt to | |
141 // reload from the incoming queue before waiting again so we clear this flag | |
142 // in ReloadWorkQueue(). | |
143 message_loop_scheduled_ = true; | |
144 } | |
114 | 145 |
115 return true; | 146 return true; |
116 } | 147 } |
117 | 148 |
118 } // namespace internal | 149 } // namespace internal |
119 } // namespace base | 150 } // namespace base |
OLD | NEW |