Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Side by Side Diff: base/message_loop/incoming_task_queue.cc

Issue 614723003: Avoid scheduling a message loop that we know is not sleeping (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/message_loop/incoming_task_queue.h ('k') | base/message_loop/message_loop.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « base/message_loop/incoming_task_queue.h ('k') | base/message_loop/message_loop.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698