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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/work_queue.cc

Issue 2258713004: Make tasks cancellable inside the blink scheduler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "platform/scheduler/base/work_queue.h" 5 #include "platform/scheduler/base/work_queue.h"
6 6
7 #include "platform/scheduler/base/work_queue_sets.h" 7 #include "platform/scheduler/base/work_queue_sets.h"
8 8
9 namespace blink { 9 namespace blink {
10 namespace scheduler { 10 namespace scheduler {
11 namespace internal { 11 namespace internal {
12 12
13 WorkQueue::WorkQueue(TaskQueueImpl* task_queue, const char* name) 13 WorkQueue::WorkQueue(TaskQueueImpl* task_queue,
14 : work_queue_sets_(nullptr), 14 const char* name,
15 TaskQueueImpl::Task::ComparatorFn comparator)
16 : work_queue_(comparator),
17 work_queue_sets_(nullptr),
15 task_queue_(task_queue), 18 task_queue_(task_queue),
16 work_queue_set_index_(0), 19 work_queue_set_index_(0),
17 name_(name) {} 20 name_(name) {}
18 21
19 void WorkQueue::AsValueInto(base::trace_event::TracedValue* state) const { 22 void WorkQueue::AsValueInto(base::trace_event::TracedValue* state) const {
20 // Remove const to search |work_queue_| in the destructive manner. Restore the 23 for (const TaskQueueImpl::Task& task : work_queue_) {
21 // content from |visited| later. 24 TaskQueueImpl::TaskAsValueInto(task, state);
22 std::queue<TaskQueueImpl::Task>* mutable_queue =
23 const_cast<std::queue<TaskQueueImpl::Task>*>(&work_queue_);
24 std::queue<TaskQueueImpl::Task> visited;
25 while (!mutable_queue->empty()) {
26 TaskQueueImpl::TaskAsValueInto(mutable_queue->front(), state);
27 visited.push(std::move(mutable_queue->front()));
28 mutable_queue->pop();
29 } 25 }
30 *mutable_queue = std::move(visited);
31 } 26 }
32 27
33 WorkQueue::~WorkQueue() { 28 WorkQueue::~WorkQueue() {
34 DCHECK(!work_queue_sets_) << task_queue_->GetName() << " : " 29 DCHECK(!work_queue_sets_) << task_queue_->GetName() << " : "
35 << work_queue_sets_->name() << " : " << name_; 30 << work_queue_sets_->name() << " : " << name_;
36 } 31 }
37 32
38 const TaskQueueImpl::Task* WorkQueue::GetFrontTask() const { 33 const TaskQueueImpl::Task* WorkQueue::GetFrontTask() const {
39 if (work_queue_.empty()) 34 if (work_queue_.empty())
40 return nullptr; 35 return nullptr;
41 return &work_queue_.front(); 36 return &*work_queue_.begin();
42 } 37 }
43 38
44 bool WorkQueue::GetFrontTaskEnqueueOrder(EnqueueOrder* enqueue_order) const { 39 bool WorkQueue::GetFrontTaskEnqueueOrder(EnqueueOrder* enqueue_order) const {
45 if (work_queue_.empty()) 40 if (work_queue_.empty())
46 return false; 41 return false;
47 *enqueue_order = work_queue_.front().enqueue_order(); 42 DCHECK_LE(work_queue_.begin()->enqueue_order(),
43 work_queue_.rbegin()->enqueue_order());
44 *enqueue_order = work_queue_.begin()->enqueue_order();
48 return true; 45 return true;
49 } 46 }
50 47
51 void WorkQueue::Push(TaskQueueImpl::Task task) { 48 void WorkQueue::Push(TaskQueueImpl::Task task) {
52 bool was_empty = work_queue_.empty(); 49 bool was_empty = work_queue_.empty();
53 work_queue_.push(std::move(task)); 50 #ifndef NDEBUG
54 if (was_empty && work_queue_sets_) 51 DCHECK(task.enqueue_order_set());
52 #endif
53
54 work_queue_.insert(std::move(task));
55 if (was_empty && work_queue_sets_) {
55 work_queue_sets_->OnPushQueue(this); 56 work_queue_sets_->OnPushQueue(this);
57 }
56 } 58 }
57 59
58 void WorkQueue::PushAndSetEnqueueOrder(TaskQueueImpl::Task task, 60 bool WorkQueue::CancelTask(const TaskQueueImpl::Task& key) {
59 EnqueueOrder enqueue_order) { 61 TaskQueueImpl::ComparatorQueue::iterator it = work_queue_.find(key);
60 bool was_empty = work_queue_.empty(); 62 if (it == work_queue_.end())
61 work_queue_.push(std::move(task)); 63 return false;
62 work_queue_.back().set_enqueue_order(enqueue_order);
63 64
64 if (was_empty && work_queue_sets_) 65 if (it == work_queue_.begin()) {
65 work_queue_sets_->OnPushQueue(this); 66 EnqueueOrder erased_task_enqueue_order = it->enqueue_order();
67 work_queue_.erase(it);
68 work_queue_sets_->OnQueueHeadChanged(this, erased_task_enqueue_order);
69 } else {
70 work_queue_.erase(it);
71 }
72 task_queue_->TraceQueueSize(false);
73 return true;
74 }
75
76 bool WorkQueue::IsTaskPending(const TaskQueueImpl::Task& key) const {
77 return work_queue_.find(key) != work_queue_.end();
66 } 78 }
67 79
68 void WorkQueue::PopTaskForTest() { 80 void WorkQueue::PopTaskForTest() {
69 work_queue_.pop(); 81 if (work_queue_.empty())
82 return;
83 work_queue_.erase(work_queue_.begin());
70 } 84 }
71 85
72 void WorkQueue::SwapLocked(std::queue<TaskQueueImpl::Task>& incoming_queue) { 86 void WorkQueue::SwapLocked(TaskQueueImpl::ComparatorQueue& incoming_queue) {
87 DCHECK(work_queue_.empty());
73 std::swap(work_queue_, incoming_queue); 88 std::swap(work_queue_, incoming_queue);
74
75 if (!work_queue_.empty() && work_queue_sets_) 89 if (!work_queue_.empty() && work_queue_sets_)
76 work_queue_sets_->OnPushQueue(this); 90 work_queue_sets_->OnPushQueue(this);
77 task_queue_->TraceQueueSize(true); 91 task_queue_->TraceQueueSize(true);
78 } 92 }
79 93
80 TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() { 94 TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() {
81 DCHECK(work_queue_sets_); 95 DCHECK(work_queue_sets_);
82 DCHECK(!work_queue_.empty()); 96 DCHECK(!work_queue_.empty());
83 TaskQueueImpl::Task pending_task = std::move(work_queue_.front()); 97 TaskQueueImpl::ComparatorQueue::iterator it = work_queue_.begin();
84 work_queue_.pop(); 98 TaskQueueImpl::Task pending_task =
99 std::move(const_cast<TaskQueueImpl::Task&>(*it));
100 work_queue_.erase(it);
85 work_queue_sets_->OnPopQueue(this); 101 work_queue_sets_->OnPopQueue(this);
86 task_queue_->TraceQueueSize(false); 102 task_queue_->TraceQueueSize(false);
87 return pending_task; 103 return pending_task;
88 } 104 }
89 105
90 void WorkQueue::AssignToWorkQueueSets(WorkQueueSets* work_queue_sets) { 106 void WorkQueue::AssignToWorkQueueSets(WorkQueueSets* work_queue_sets) {
91 work_queue_sets_ = work_queue_sets; 107 work_queue_sets_ = work_queue_sets;
92 } 108 }
93 109
94 void WorkQueue::AssignSetIndex(size_t work_queue_set_index) { 110 void WorkQueue::AssignSetIndex(size_t work_queue_set_index) {
95 work_queue_set_index_ = work_queue_set_index; 111 work_queue_set_index_ = work_queue_set_index;
96 } 112 }
97 113
98 bool WorkQueue::ShouldRunBefore(const WorkQueue* other_queue) const { 114 bool WorkQueue::ShouldRunBefore(const WorkQueue* other_queue) const {
99 DCHECK(!work_queue_.empty()); 115 DCHECK(!work_queue_.empty());
100 DCHECK(!other_queue->work_queue_.empty()); 116 DCHECK(!other_queue->work_queue_.empty());
101 EnqueueOrder enqueue_order = 0; 117 EnqueueOrder enqueue_order = 0;
102 EnqueueOrder other_enqueue_order = 0; 118 EnqueueOrder other_enqueue_order = 0;
103 bool have_task = GetFrontTaskEnqueueOrder(&enqueue_order); 119 bool have_task = GetFrontTaskEnqueueOrder(&enqueue_order);
104 bool have_other_task = 120 bool have_other_task =
105 other_queue->GetFrontTaskEnqueueOrder(&other_enqueue_order); 121 other_queue->GetFrontTaskEnqueueOrder(&other_enqueue_order);
106 DCHECK(have_task); 122 DCHECK(have_task);
107 DCHECK(have_other_task); 123 DCHECK(have_other_task);
108 return enqueue_order < other_enqueue_order; 124 return enqueue_order < other_enqueue_order;
109 } 125 }
110 126
111 } // namespace internal 127 } // namespace internal
112 } // namespace scheduler 128 } // namespace scheduler
113 } // namespace blink 129 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698