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

Side by Side Diff: components/scheduler/base/task_queue_selector_unittest.cc

Issue 1685093002: Fix bug with TaskQueueSelector and blocked queues (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix UAF Created 4 years, 10 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 "components/scheduler/base/task_queue_selector.h" 5 #include "components/scheduler/base/task_queue_selector.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 for (size_t i = 0; i < kTaskQueueCount; i++) { 119 for (size_t i = 0; i < kTaskQueueCount; i++) {
120 EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[i]->GetQueuePriority()) 120 EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[i]->GetQueuePriority())
121 << i; 121 << i;
122 queue_to_index_map_.insert(std::make_pair(task_queues_[i].get(), i)); 122 queue_to_index_map_.insert(std::make_pair(task_queues_[i].get(), i));
123 } 123 }
124 } 124 }
125 125
126 void TearDown() final { 126 void TearDown() final {
127 for (scoped_refptr<TaskQueueImpl>& task_queue : task_queues_) { 127 for (scoped_refptr<TaskQueueImpl>& task_queue : task_queues_) {
128 task_queue->UnregisterTaskQueue(); 128 task_queue->UnregisterTaskQueue();
129 // Note since this test doesn't have a TaskQueueManager we need to
130 // manually remove |task_queue| from the |selector_|. Normally
131 // UnregisterTaskQueue would do that.
132 selector_.RemoveQueue(task_queue.get());
129 } 133 }
130 } 134 }
131 135
132 scoped_refptr<TaskQueueImpl> NewTaskQueueWithBlockReporting() { 136 scoped_refptr<TaskQueueImpl> NewTaskQueueWithBlockReporting() {
133 return make_scoped_refptr(new TaskQueueImpl( 137 return make_scoped_refptr(new TaskQueueImpl(
134 nullptr, virtual_time_domain_.get(), 138 nullptr, virtual_time_domain_.get(),
135 TaskQueue::Spec("test queue").SetShouldReportWhenExecutionBlocked(true), 139 TaskQueue::Spec("test queue").SetShouldReportWhenExecutionBlocked(true),
136 "test", "test")); 140 "test", "test"));
137 } 141 }
138 142
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 TEST_F(TaskQueueSelectorTest, TestObserverWithEnabledQueue) { 184 TEST_F(TaskQueueSelectorTest, TestObserverWithEnabledQueue) {
181 DisableQueue(task_queues_[1].get()); 185 DisableQueue(task_queues_[1].get());
182 MockObserver mock_observer; 186 MockObserver mock_observer;
183 selector_.SetTaskQueueSelectorObserver(&mock_observer); 187 selector_.SetTaskQueueSelectorObserver(&mock_observer);
184 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1); 188 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1);
185 EnableQueue(task_queues_[1].get()); 189 EnableQueue(task_queues_[1].get());
186 } 190 }
187 191
188 TEST_F(TaskQueueSelectorTest, 192 TEST_F(TaskQueueSelectorTest,
189 TestObserverWithSetQueuePriorityAndQueueAlreadyEnabled) { 193 TestObserverWithSetQueuePriorityAndQueueAlreadyEnabled) {
190 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY); 194 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY);
191 MockObserver mock_observer; 195 MockObserver mock_observer;
192 selector_.SetTaskQueueSelectorObserver(&mock_observer); 196 selector_.SetTaskQueueSelectorObserver(&mock_observer);
193 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(0); 197 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(0);
194 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY); 198 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY);
195 } 199 }
196 200
197 TEST_F(TaskQueueSelectorTest, TestDisableEnable) { 201 TEST_F(TaskQueueSelectorTest, TestDisableEnable) {
198 MockObserver mock_observer; 202 MockObserver mock_observer;
199 selector_.SetTaskQueueSelectorObserver(&mock_observer); 203 selector_.SetTaskQueueSelectorObserver(&mock_observer);
200 204
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 EXPECT_GT(counts[0], 0ul); // Check high doesn't starve normal. 291 EXPECT_GT(counts[0], 0ul); // Check high doesn't starve normal.
288 EXPECT_GT(counts[2], counts[0]); // Check high gets more chance to run. 292 EXPECT_GT(counts[2], counts[0]); // Check high gets more chance to run.
289 EXPECT_EQ(0ul, counts[1]); // Check best effort is starved. 293 EXPECT_EQ(0ul, counts[1]); // Check best effort is starved.
290 } 294 }
291 295
292 TEST_F(TaskQueueSelectorTest, TestBestEffortGetsStarved) { 296 TEST_F(TaskQueueSelectorTest, TestBestEffortGetsStarved) {
293 size_t queue_order[] = {0, 1}; 297 size_t queue_order[] = {0, 1};
294 PushTasks(queue_order, 2); 298 PushTasks(queue_order, 2);
295 selector_.SetQueuePriority(task_queues_[0].get(), 299 selector_.SetQueuePriority(task_queues_[0].get(),
296 TaskQueue::BEST_EFFORT_PRIORITY); 300 TaskQueue::BEST_EFFORT_PRIORITY);
297 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY); 301 EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[1]->GetQueuePriority());
298 WorkQueue* chosen_work_queue = nullptr; 302 WorkQueue* chosen_work_queue = nullptr;
299 for (int i = 0; i < 100; i++) { 303 for (int i = 0; i < 100; i++) {
300 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); 304 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
301 EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); 305 EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue());
302 // Don't remove task from queue to simulate all queues still being full. 306 // Don't remove task from queue to simulate all queues still being full.
303 } 307 }
304 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY); 308 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY);
305 for (int i = 0; i < 100; i++) { 309 for (int i = 0; i < 100; i++) {
306 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); 310 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
307 EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); 311 EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 387
384 task_queue->immediate_work_queue()->PushAndSetEnqueueOrder( 388 task_queue->immediate_work_queue()->PushAndSetEnqueueOrder(
385 TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, true), 389 TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, true),
386 0); 390 0);
387 391
388 WorkQueue* chosen_work_queue; 392 WorkQueue* chosen_work_queue;
389 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); 393 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1);
390 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); 394 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue));
391 395
392 task_queue->UnregisterTaskQueue(); 396 task_queue->UnregisterTaskQueue();
397 selector.RemoveQueue(task_queue.get());
393 } 398 }
394 399
395 TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) { 400 TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) {
396 TaskQueueSelectorForTest selector; 401 TaskQueueSelectorForTest selector;
397 MockObserver mock_observer; 402 MockObserver mock_observer;
398 selector.SetTaskQueueSelectorObserver(&mock_observer); 403 selector.SetTaskQueueSelectorObserver(&mock_observer);
399 404
400 scoped_refptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting()); 405 scoped_refptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting());
401 scoped_refptr<TaskQueueImpl> task_queue2(NewTaskQueueWithBlockReporting()); 406 scoped_refptr<TaskQueueImpl> task_queue2(NewTaskQueueWithBlockReporting());
402 selector.AddQueue(task_queue.get()); 407 selector.AddQueue(task_queue.get());
(...skipping 12 matching lines...) Expand all
415 0); 420 0);
416 421
417 // Should still only see one call to OnTriedToSelectBlockedWorkQueue. 422 // Should still only see one call to OnTriedToSelectBlockedWorkQueue.
418 WorkQueue* chosen_work_queue; 423 WorkQueue* chosen_work_queue;
419 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); 424 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1);
420 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); 425 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue));
421 testing::Mock::VerifyAndClearExpectations(&mock_observer); 426 testing::Mock::VerifyAndClearExpectations(&mock_observer);
422 427
423 // Removing the second queue and selecting again should result in another 428 // Removing the second queue and selecting again should result in another
424 // notification. 429 // notification.
430 task_queue->UnregisterTaskQueue();
425 selector.RemoveQueue(task_queue.get()); 431 selector.RemoveQueue(task_queue.get());
426 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); 432 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1);
427 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); 433 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue));
428 434
429 task_queue->UnregisterTaskQueue();
430 task_queue2->UnregisterTaskQueue(); 435 task_queue2->UnregisterTaskQueue();
436 selector.RemoveQueue(task_queue2.get());
431 } 437 }
432 438
433 struct ChooseOldestWithPriorityTestParam { 439 struct ChooseOldestWithPriorityTestParam {
434 int delayed_task_enqueue_order; 440 int delayed_task_enqueue_order;
435 int immediate_task_enqueue_order; 441 int immediate_task_enqueue_order;
436 int immediate_starvation_count; 442 int immediate_starvation_count;
437 const char* expected_work_queue_name; 443 const char* expected_work_queue_name;
438 bool expected_did_starve_immediate_queue; 444 bool expected_did_starve_immediate_queue;
439 }; 445 };
440 446
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 EXPECT_EQ(chose_delayed_over_immediate, 483 EXPECT_EQ(chose_delayed_over_immediate,
478 GetParam().expected_did_starve_immediate_queue); 484 GetParam().expected_did_starve_immediate_queue);
479 } 485 }
480 486
481 INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest, 487 INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest,
482 ChooseOldestWithPriorityTest, 488 ChooseOldestWithPriorityTest,
483 testing::ValuesIn(kChooseOldestWithPriorityTestCases)); 489 testing::ValuesIn(kChooseOldestWithPriorityTestCases));
484 490
485 } // namespace internal 491 } // namespace internal
486 } // namespace scheduler 492 } // namespace scheduler
OLDNEW
« no previous file with comments | « components/scheduler/base/task_queue_selector.cc ('k') | components/scheduler/base/work_queue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698