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

Side by Side Diff: base/task_scheduler/scheduler_worker_unittest.cc

Issue 2427963002: Support FileDescriptorWatcher in TaskScheduler. (Closed)
Patch Set: nacl Created 4 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/task_scheduler/scheduler_worker.h" 5 #include "base/task_scheduler/scheduler_worker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/message_loop/message_loop.h"
16 #include "base/synchronization/condition_variable.h" 17 #include "base/synchronization/condition_variable.h"
17 #include "base/synchronization/waitable_event.h" 18 #include "base/synchronization/waitable_event.h"
18 #include "base/task_scheduler/scheduler_lock.h" 19 #include "base/task_scheduler/scheduler_lock.h"
19 #include "base/task_scheduler/sequence.h" 20 #include "base/task_scheduler/sequence.h"
20 #include "base/task_scheduler/task.h" 21 #include "base/task_scheduler/task.h"
21 #include "base/task_scheduler/task_tracker.h" 22 #include "base/task_scheduler/task_tracker.h"
22 #include "base/threading/platform_thread.h" 23 #include "base/threading/platform_thread.h"
23 #include "base/time/time.h" 24 #include "base/time/time.h"
24 #include "build/build_config.h" 25 #include "build/build_config.h"
25 #include "testing/gmock/include/gmock/gmock.h" 26 #include "testing/gmock/include/gmock/gmock.h"
(...skipping 28 matching lines...) Expand all
54 ADD_FAILURE() << "Unexpected call to ReEnqueueSequence()"; 55 ADD_FAILURE() << "Unexpected call to ReEnqueueSequence()";
55 } 56 }
56 TimeDelta GetSleepTimeout() override { return TimeDelta::Max(); } 57 TimeDelta GetSleepTimeout() override { return TimeDelta::Max(); }
57 bool CanDetach(SchedulerWorker* worker) override { return false; } 58 bool CanDetach(SchedulerWorker* worker) override { return false; }
58 59
59 private: 60 private:
60 DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerDefaultDelegate); 61 DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerDefaultDelegate);
61 }; 62 };
62 63
63 // The test parameter is the number of Tasks per Sequence returned by GetWork(). 64 // The test parameter is the number of Tasks per Sequence returned by GetWork().
64 class TaskSchedulerWorkerTest : public testing::TestWithParam<size_t> { 65 class TaskSchedulerWorkerDoWorkTest : public testing::TestWithParam<size_t> {
65 protected: 66 protected:
66 TaskSchedulerWorkerTest() 67 TaskSchedulerWorkerDoWorkTest()
67 : main_entry_called_(WaitableEvent::ResetPolicy::MANUAL, 68 :
69 #if defined(OS_POSIX) && !defined(OS_NACL_SFI)
70 task_tracker_(&watch_file_descriptor_message_loop_),
71 #endif
72 main_entry_called_(WaitableEvent::ResetPolicy::MANUAL,
68 WaitableEvent::InitialState::NOT_SIGNALED), 73 WaitableEvent::InitialState::NOT_SIGNALED),
69 num_get_work_cv_(lock_.CreateConditionVariable()), 74 num_get_work_cv_(lock_.CreateConditionVariable()),
70 worker_set_(WaitableEvent::ResetPolicy::MANUAL, 75 worker_set_(WaitableEvent::ResetPolicy::MANUAL,
71 WaitableEvent::InitialState::NOT_SIGNALED) {} 76 WaitableEvent::InitialState::NOT_SIGNALED) {
77 }
72 78
73 void SetUp() override { 79 void SetUp() override {
74 worker_ = SchedulerWorker::Create( 80 worker_ = SchedulerWorker::Create(
75 ThreadPriority::NORMAL, MakeUnique<TestSchedulerWorkerDelegate>(this), 81 ThreadPriority::NORMAL, MakeUnique<TestSchedulerWorkerDelegate>(this),
76 &task_tracker_, SchedulerWorker::InitialState::ALIVE); 82 &task_tracker_, SchedulerWorker::InitialState::ALIVE);
77 ASSERT_TRUE(worker_); 83 ASSERT_TRUE(worker_);
78 worker_set_.Signal(); 84 worker_set_.Signal();
79 main_entry_called_.Wait(); 85 main_entry_called_.Wait();
80 } 86 }
81 87
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 std::vector<scoped_refptr<Sequence>> EnqueuedSequences() { 122 std::vector<scoped_refptr<Sequence>> EnqueuedSequences() {
117 AutoSchedulerLock auto_lock(lock_); 123 AutoSchedulerLock auto_lock(lock_);
118 return re_enqueued_sequences_; 124 return re_enqueued_sequences_;
119 } 125 }
120 126
121 std::unique_ptr<SchedulerWorker> worker_; 127 std::unique_ptr<SchedulerWorker> worker_;
122 128
123 private: 129 private:
124 class TestSchedulerWorkerDelegate : public SchedulerWorkerDefaultDelegate { 130 class TestSchedulerWorkerDelegate : public SchedulerWorkerDefaultDelegate {
125 public: 131 public:
126 TestSchedulerWorkerDelegate(TaskSchedulerWorkerTest* outer) 132 TestSchedulerWorkerDelegate(TaskSchedulerWorkerDoWorkTest* outer)
127 : outer_(outer) {} 133 : outer_(outer) {}
128 134
129 ~TestSchedulerWorkerDelegate() override { 135 ~TestSchedulerWorkerDelegate() override {
130 EXPECT_FALSE(IsCallToDidRunTaskWithPriorityExpected()); 136 EXPECT_FALSE(IsCallToDidRunTaskWithPriorityExpected());
131 } 137 }
132 138
133 // SchedulerWorker::Delegate: 139 // SchedulerWorker::Delegate:
134 void OnMainEntry(SchedulerWorker* worker, 140 void OnMainEntry(SchedulerWorker* worker,
135 const TimeDelta& detach_duration) override { 141 const TimeDelta& detach_duration) override {
136 outer_->worker_set_.Wait(); 142 outer_->worker_set_.Wait();
(...skipping 24 matching lines...) Expand all
161 // Check if a Sequence should be returned. 167 // Check if a Sequence should be returned.
162 if (outer_->num_sequences_to_create_ == 0) 168 if (outer_->num_sequences_to_create_ == 0)
163 return nullptr; 169 return nullptr;
164 --outer_->num_sequences_to_create_; 170 --outer_->num_sequences_to_create_;
165 } 171 }
166 172
167 // Create a Sequence with TasksPerSequence() Tasks. 173 // Create a Sequence with TasksPerSequence() Tasks.
168 scoped_refptr<Sequence> sequence(new Sequence); 174 scoped_refptr<Sequence> sequence(new Sequence);
169 for (size_t i = 0; i < outer_->TasksPerSequence(); ++i) { 175 for (size_t i = 0; i < outer_->TasksPerSequence(); ++i) {
170 std::unique_ptr<Task> task(new Task( 176 std::unique_ptr<Task> task(new Task(
171 FROM_HERE, Bind(&TaskSchedulerWorkerTest::RunTaskCallback, 177 FROM_HERE, Bind(&TaskSchedulerWorkerDoWorkTest::RunTaskCallback,
172 Unretained(outer_)), 178 Unretained(outer_)),
173 TaskTraits(), TimeDelta())); 179 TaskTraits(), TimeDelta()));
174 EXPECT_TRUE(outer_->task_tracker_.WillPostTask(task.get())); 180 EXPECT_TRUE(outer_->task_tracker_.WillPostTask(task.get()));
175 sequence->PushTask(std::move(task)); 181 sequence->PushTask(std::move(task));
176 } 182 }
177 183
178 ExpectCallToDidRunTaskWithPriority(sequence->PeekTaskTraits().priority()); 184 ExpectCallToDidRunTaskWithPriority(sequence->PeekTaskTraits().priority());
179 185
180 { 186 {
181 // Add the Sequence to the vector of created Sequences. 187 // Add the Sequence to the vector of created Sequences.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 AutoSchedulerLock auto_lock(expect_did_run_task_with_priority_lock_); 229 AutoSchedulerLock auto_lock(expect_did_run_task_with_priority_lock_);
224 expect_did_run_task_with_priority_ = true; 230 expect_did_run_task_with_priority_ = true;
225 expected_task_priority_ = task_priority; 231 expected_task_priority_ = task_priority;
226 } 232 }
227 233
228 bool IsCallToDidRunTaskWithPriorityExpected() const { 234 bool IsCallToDidRunTaskWithPriorityExpected() const {
229 AutoSchedulerLock auto_lock(expect_did_run_task_with_priority_lock_); 235 AutoSchedulerLock auto_lock(expect_did_run_task_with_priority_lock_);
230 return expect_did_run_task_with_priority_; 236 return expect_did_run_task_with_priority_;
231 } 237 }
232 238
233 TaskSchedulerWorkerTest* outer_; 239 TaskSchedulerWorkerDoWorkTest* const outer_;
234 240
235 // Synchronizes access to |expect_did_run_task_with_priority_| and 241 // Synchronizes access to |expect_did_run_task_with_priority_| and
236 // |expected_task_priority_|. 242 // |expected_task_priority_|.
237 mutable SchedulerLock expect_did_run_task_with_priority_lock_; 243 mutable SchedulerLock expect_did_run_task_with_priority_lock_;
238 244
239 // Whether the next method called on this delegate should be 245 // Whether the next method called on this delegate should be
240 // DidRunTaskWithPriority(). 246 // DidRunTaskWithPriority().
241 bool expect_did_run_task_with_priority_ = false; 247 bool expect_did_run_task_with_priority_ = false;
242 248
243 // Expected priority for the next call to DidRunTaskWithPriority(). 249 // Expected priority for the next call to DidRunTaskWithPriority().
244 TaskPriority expected_task_priority_ = TaskPriority::BACKGROUND; 250 TaskPriority expected_task_priority_ = TaskPriority::BACKGROUND;
245 }; 251 };
246 252
247 void RunTaskCallback() { 253 void RunTaskCallback() {
248 AutoSchedulerLock auto_lock(lock_); 254 AutoSchedulerLock auto_lock(lock_);
249 ++num_run_tasks_; 255 ++num_run_tasks_;
250 EXPECT_LE(num_run_tasks_, created_sequences_.size()); 256 EXPECT_LE(num_run_tasks_, created_sequences_.size());
251 } 257 }
252 258
259 private:
260 #if defined(OS_POSIX) && !defined(OS_NACL_SFI)
261 MessageLoopForIO watch_file_descriptor_message_loop_;
262 #endif
263
264 protected:
253 TaskTracker task_tracker_; 265 TaskTracker task_tracker_;
254 266
255 // Synchronizes access to all members below. 267 // Synchronizes access to all members below.
256 mutable SchedulerLock lock_; 268 mutable SchedulerLock lock_;
257 269
258 // Signaled once OnMainEntry() has been called. 270 // Signaled once OnMainEntry() has been called.
259 WaitableEvent main_entry_called_; 271 WaitableEvent main_entry_called_;
260 272
261 // Number of Sequences that should be created by GetWork(). When this 273 // Number of Sequences that should be created by GetWork(). When this
262 // is 0, GetWork() returns nullptr. 274 // is 0, GetWork() returns nullptr.
(...skipping 13 matching lines...) Expand all
276 288
277 // Sequences passed to EnqueueSequence(). 289 // Sequences passed to EnqueueSequence().
278 std::vector<scoped_refptr<Sequence>> re_enqueued_sequences_; 290 std::vector<scoped_refptr<Sequence>> re_enqueued_sequences_;
279 291
280 // Number of times that RunTaskCallback() has been called. 292 // Number of times that RunTaskCallback() has been called.
281 size_t num_run_tasks_ = 0; 293 size_t num_run_tasks_ = 0;
282 294
283 // Signaled after |worker_| is set. 295 // Signaled after |worker_| is set.
284 WaitableEvent worker_set_; 296 WaitableEvent worker_set_;
285 297
286 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerTest); 298 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerDoWorkTest);
287 }; 299 };
288 300
289 // Verify that when GetWork() continuously returns Sequences, all Tasks in these 301 // Verify that when GetWork() continuously returns Sequences, all Tasks in these
290 // Sequences run successfully. The test wakes up the SchedulerWorker once. 302 // Sequences run successfully. The test wakes up the SchedulerWorker once.
291 TEST_P(TaskSchedulerWorkerTest, ContinuousWork) { 303 TEST_P(TaskSchedulerWorkerDoWorkTest, ContinuousWork) {
292 // Set GetWork() to return |kNumSequencesPerTest| Sequences before starting to 304 // Set GetWork() to return |kNumSequencesPerTest| Sequences before starting to
293 // return nullptr. 305 // return nullptr.
294 SetNumSequencesToCreate(kNumSequencesPerTest); 306 SetNumSequencesToCreate(kNumSequencesPerTest);
295 307
296 // Expect |kNumSequencesPerTest| calls to GetWork() in which it returns a 308 // Expect |kNumSequencesPerTest| calls to GetWork() in which it returns a
297 // Sequence and one call in which its returns nullptr. 309 // Sequence and one call in which its returns nullptr.
298 const size_t kExpectedNumGetWork = kNumSequencesPerTest + 1; 310 const size_t kExpectedNumGetWork = kNumSequencesPerTest + 1;
299 SetMaxGetWork(kExpectedNumGetWork); 311 SetMaxGetWork(kExpectedNumGetWork);
300 312
301 // Wake up |worker_| and wait until GetWork() has been invoked the 313 // Wake up |worker_| and wait until GetWork() has been invoked the
302 // expected amount of times. 314 // expected amount of times.
303 worker_->WakeUp(); 315 worker_->WakeUp();
304 WaitForNumGetWork(kExpectedNumGetWork); 316 WaitForNumGetWork(kExpectedNumGetWork);
305 317
306 // All tasks should have run. 318 // All tasks should have run.
307 EXPECT_EQ(kNumSequencesPerTest, NumRunTasks()); 319 EXPECT_EQ(kNumSequencesPerTest, NumRunTasks());
308 320
309 // If Sequences returned by GetWork() contain more than one Task, they aren't 321 // If Sequences returned by GetWork() contain more than one Task, they aren't
310 // empty after the worker pops Tasks from them and thus should be returned to 322 // empty after the worker pops Tasks from them and thus should be returned to
311 // EnqueueSequence(). 323 // EnqueueSequence().
312 if (TasksPerSequence() > 1) 324 if (TasksPerSequence() > 1)
313 EXPECT_EQ(CreatedSequences(), EnqueuedSequences()); 325 EXPECT_EQ(CreatedSequences(), EnqueuedSequences());
314 else 326 else
315 EXPECT_TRUE(EnqueuedSequences().empty()); 327 EXPECT_TRUE(EnqueuedSequences().empty());
316 } 328 }
317 329
318 // Verify that when GetWork() alternates between returning a Sequence and 330 // Verify that when GetWork() alternates between returning a Sequence and
319 // returning nullptr, all Tasks in the returned Sequences run successfully. The 331 // returning nullptr, all Tasks in the returned Sequences run successfully. The
320 // test wakes up the SchedulerWorker once for each Sequence. 332 // test wakes up the SchedulerWorker once for each Sequence.
321 TEST_P(TaskSchedulerWorkerTest, IntermittentWork) { 333 TEST_P(TaskSchedulerWorkerDoWorkTest, IntermittentWork) {
322 for (size_t i = 0; i < kNumSequencesPerTest; ++i) { 334 for (size_t i = 0; i < kNumSequencesPerTest; ++i) {
323 // Set GetWork() to return 1 Sequence before starting to return 335 // Set GetWork() to return 1 Sequence before starting to return
324 // nullptr. 336 // nullptr.
325 SetNumSequencesToCreate(1); 337 SetNumSequencesToCreate(1);
326 338
327 // Expect |i + 1| calls to GetWork() in which it returns a Sequence and 339 // Expect |i + 1| calls to GetWork() in which it returns a Sequence and
328 // |i + 1| calls in which it returns nullptr. 340 // |i + 1| calls in which it returns nullptr.
329 const size_t expected_num_get_work = 2 * (i + 1); 341 const size_t expected_num_get_work = 2 * (i + 1);
330 SetMaxGetWork(expected_num_get_work); 342 SetMaxGetWork(expected_num_get_work);
331 343
332 // Wake up |worker_| and wait until GetWork() has been invoked 344 // Wake up |worker_| and wait until GetWork() has been invoked
333 // the expected amount of times. 345 // the expected amount of times.
334 worker_->WakeUp(); 346 worker_->WakeUp();
335 WaitForNumGetWork(expected_num_get_work); 347 WaitForNumGetWork(expected_num_get_work);
336 348
337 // The Task should have run 349 // The Task should have run
338 EXPECT_EQ(i + 1, NumRunTasks()); 350 EXPECT_EQ(i + 1, NumRunTasks());
339 351
340 // If Sequences returned by GetWork() contain more than one Task, they 352 // If Sequences returned by GetWork() contain more than one Task, they
341 // aren't empty after the worker pops Tasks from them and thus should be 353 // aren't empty after the worker pops Tasks from them and thus should be
342 // returned to EnqueueSequence(). 354 // returned to EnqueueSequence().
343 if (TasksPerSequence() > 1) 355 if (TasksPerSequence() > 1)
344 EXPECT_EQ(CreatedSequences(), EnqueuedSequences()); 356 EXPECT_EQ(CreatedSequences(), EnqueuedSequences());
345 else 357 else
346 EXPECT_TRUE(EnqueuedSequences().empty()); 358 EXPECT_TRUE(EnqueuedSequences().empty());
347 } 359 }
348 } 360 }
349 361
350 INSTANTIATE_TEST_CASE_P(OneTaskPerSequence, 362 INSTANTIATE_TEST_CASE_P(OneTaskPerSequence,
351 TaskSchedulerWorkerTest, 363 TaskSchedulerWorkerDoWorkTest,
352 ::testing::Values(1)); 364 ::testing::Values(1));
353 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, 365 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence,
354 TaskSchedulerWorkerTest, 366 TaskSchedulerWorkerDoWorkTest,
355 ::testing::Values(2)); 367 ::testing::Values(2));
356 368
357 namespace { 369 namespace {
358 370
359 class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate { 371 class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate {
360 public: 372 public:
361 ControllableDetachDelegate(TaskTracker* task_tracker) 373 ControllableDetachDelegate(TaskTracker* task_tracker)
362 : task_tracker_(task_tracker), 374 : task_tracker_(task_tracker),
363 work_processed_(WaitableEvent::ResetPolicy::MANUAL, 375 work_processed_(WaitableEvent::ResetPolicy::MANUAL,
364 WaitableEvent::InitialState::NOT_SIGNALED), 376 WaitableEvent::InitialState::NOT_SIGNALED),
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 private: 429 private:
418 TaskTracker* const task_tracker_; 430 TaskTracker* const task_tracker_;
419 bool work_requested_ = false; 431 bool work_requested_ = false;
420 bool can_detach_ = false; 432 bool can_detach_ = false;
421 WaitableEvent work_processed_; 433 WaitableEvent work_processed_;
422 WaitableEvent detach_requested_; 434 WaitableEvent detach_requested_;
423 435
424 DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate); 436 DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate);
425 }; 437 };
426 438
439 class TaskSchedulerWorkerTest : public testing::Test {
440 public:
441 TaskSchedulerWorkerTest()
442 #if defined(OS_POSIX) && !defined(OS_NACL_SFI)
443 : task_tracker_(&service_message_loop_)
444 #endif
445 {
446 }
447
448 #if defined(OS_POSIX) && !defined(OS_NACL_SFI)
449 private:
450 MessageLoopForIO service_message_loop_;
451 #endif
452
453 protected:
454 TaskTracker task_tracker_;
455
456 private:
457 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerTest);
458 };
459
427 } // namespace 460 } // namespace
428 461
429 TEST(TaskSchedulerWorkerTest, WorkerDetaches) { 462 TEST_F(TaskSchedulerWorkerTest, WorkerDetaches) {
430 TaskTracker task_tracker;
431 // Will be owned by SchedulerWorker. 463 // Will be owned by SchedulerWorker.
432 ControllableDetachDelegate* delegate = 464 ControllableDetachDelegate* delegate =
433 new StrictMock<ControllableDetachDelegate>(&task_tracker); 465 new StrictMock<ControllableDetachDelegate>(&task_tracker_);
434 delegate->set_can_detach(true); 466 delegate->set_can_detach(true);
435 EXPECT_CALL(*delegate, OnMainEntry(_, TimeDelta::Max())); 467 EXPECT_CALL(*delegate, OnMainEntry(_, TimeDelta::Max()));
436 std::unique_ptr<SchedulerWorker> worker = 468 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create(
437 SchedulerWorker::Create( 469 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker_,
438 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, 470 SchedulerWorker::InitialState::ALIVE);
439 SchedulerWorker::InitialState::ALIVE);
440 worker->WakeUp(); 471 worker->WakeUp();
441 delegate->WaitForWorkToRun(); 472 delegate->WaitForWorkToRun();
442 Mock::VerifyAndClear(delegate); 473 Mock::VerifyAndClear(delegate);
443 delegate->WaitForDetachRequest(); 474 delegate->WaitForDetachRequest();
444 // Sleep to give a chance for the detach to happen. A yield is too short. 475 // Sleep to give a chance for the detach to happen. A yield is too short.
445 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); 476 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
446 ASSERT_FALSE(worker->ThreadAliveForTesting()); 477 ASSERT_FALSE(worker->ThreadAliveForTesting());
447 } 478 }
448 479
449 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) { 480 TEST_F(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) {
450 TaskTracker task_tracker;
451 // Will be owned by SchedulerWorker. 481 // Will be owned by SchedulerWorker.
452 ControllableDetachDelegate* delegate = 482 ControllableDetachDelegate* delegate =
453 new StrictMock<ControllableDetachDelegate>(&task_tracker); 483 new StrictMock<ControllableDetachDelegate>(&task_tracker_);
454 delegate->set_can_detach(true); 484 delegate->set_can_detach(true);
455 EXPECT_CALL(*delegate, OnMainEntry(_, TimeDelta::Max())); 485 EXPECT_CALL(*delegate, OnMainEntry(_, TimeDelta::Max()));
456 std::unique_ptr<SchedulerWorker> worker = 486 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create(
457 SchedulerWorker::Create( 487 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker_,
458 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, 488 SchedulerWorker::InitialState::ALIVE);
459 SchedulerWorker::InitialState::ALIVE);
460 worker->WakeUp(); 489 worker->WakeUp();
461 delegate->WaitForWorkToRun(); 490 delegate->WaitForWorkToRun();
462 Mock::VerifyAndClear(delegate); 491 Mock::VerifyAndClear(delegate);
463 delegate->WaitForDetachRequest(); 492 delegate->WaitForDetachRequest();
464 // Sleep to give a chance for the detach to happen. A yield is too short. 493 // Sleep to give a chance for the detach to happen. A yield is too short.
465 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); 494 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
466 ASSERT_FALSE(worker->ThreadAliveForTesting()); 495 ASSERT_FALSE(worker->ThreadAliveForTesting());
467 496
468 delegate->ResetState(); 497 delegate->ResetState();
469 delegate->set_can_detach(false); 498 delegate->set_can_detach(false);
470 // When SchedulerWorker recreates its thread, expect OnMainEntry() to be 499 // When SchedulerWorker recreates its thread, expect OnMainEntry() to be
471 // called with a detach duration which is not TimeDelta::Max(). 500 // called with a detach duration which is not TimeDelta::Max().
472 EXPECT_CALL(*delegate, OnMainEntry(worker.get(), Ne(TimeDelta::Max()))); 501 EXPECT_CALL(*delegate, OnMainEntry(worker.get(), Ne(TimeDelta::Max())));
473 worker->WakeUp(); 502 worker->WakeUp();
474 delegate->WaitForWorkToRun(); 503 delegate->WaitForWorkToRun();
475 Mock::VerifyAndClear(delegate); 504 Mock::VerifyAndClear(delegate);
476 delegate->WaitForDetachRequest(); 505 delegate->WaitForDetachRequest();
477 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); 506 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
478 ASSERT_TRUE(worker->ThreadAliveForTesting()); 507 ASSERT_TRUE(worker->ThreadAliveForTesting());
479 worker->JoinForTesting(); 508 worker->JoinForTesting();
480 } 509 }
481 510
482 TEST(TaskSchedulerWorkerTest, CreateDetached) { 511 TEST_F(TaskSchedulerWorkerTest, CreateDetached) {
483 TaskTracker task_tracker;
484 // Will be owned by SchedulerWorker. 512 // Will be owned by SchedulerWorker.
485 ControllableDetachDelegate* delegate = 513 ControllableDetachDelegate* delegate =
486 new StrictMock<ControllableDetachDelegate>(&task_tracker); 514 new StrictMock<ControllableDetachDelegate>(&task_tracker_);
487 std::unique_ptr<SchedulerWorker> worker = 515 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create(
488 SchedulerWorker::Create( 516 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker_,
489 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, 517 SchedulerWorker::InitialState::DETACHED);
490 SchedulerWorker::InitialState::DETACHED);
491 ASSERT_FALSE(worker->ThreadAliveForTesting()); 518 ASSERT_FALSE(worker->ThreadAliveForTesting());
492 EXPECT_CALL(*delegate, OnMainEntry(worker.get(), TimeDelta::Max())); 519 EXPECT_CALL(*delegate, OnMainEntry(worker.get(), TimeDelta::Max()));
493 worker->WakeUp(); 520 worker->WakeUp();
494 delegate->WaitForWorkToRun(); 521 delegate->WaitForWorkToRun();
495 Mock::VerifyAndClear(delegate); 522 Mock::VerifyAndClear(delegate);
496 delegate->WaitForDetachRequest(); 523 delegate->WaitForDetachRequest();
497 ASSERT_TRUE(worker->ThreadAliveForTesting()); 524 ASSERT_TRUE(worker->ThreadAliveForTesting());
498 worker->JoinForTesting(); 525 worker->JoinForTesting();
499 } 526 }
500 527
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 SchedulerLock expected_thread_priority_lock_; 568 SchedulerLock expected_thread_priority_lock_;
542 569
543 // Expected thread priority for the next call to OnMainEntry() or GetWork(). 570 // Expected thread priority for the next call to OnMainEntry() or GetWork().
544 ThreadPriority expected_thread_priority_; 571 ThreadPriority expected_thread_priority_;
545 572
546 DISALLOW_COPY_AND_ASSIGN(ExpectThreadPriorityDelegate); 573 DISALLOW_COPY_AND_ASSIGN(ExpectThreadPriorityDelegate);
547 }; 574 };
548 575
549 } // namespace 576 } // namespace
550 577
551 TEST(TaskSchedulerWorkerTest, BumpPriorityOfAliveThreadDuringShutdown) { 578 TEST_F(TaskSchedulerWorkerTest, BumpPriorityOfAliveThreadDuringShutdown) {
552 TaskTracker task_tracker;
553
554 std::unique_ptr<ExpectThreadPriorityDelegate> delegate( 579 std::unique_ptr<ExpectThreadPriorityDelegate> delegate(
555 new ExpectThreadPriorityDelegate); 580 new ExpectThreadPriorityDelegate);
556 ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); 581 ExpectThreadPriorityDelegate* delegate_raw = delegate.get();
557 delegate_raw->SetExpectedThreadPriority( 582 delegate_raw->SetExpectedThreadPriority(
558 PlatformThread::CanIncreaseCurrentThreadPriority() 583 PlatformThread::CanIncreaseCurrentThreadPriority()
559 ? ThreadPriority::BACKGROUND 584 ? ThreadPriority::BACKGROUND
560 : ThreadPriority::NORMAL); 585 : ThreadPriority::NORMAL);
561 586
562 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( 587 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create(
563 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, 588 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker_,
564 SchedulerWorker::InitialState::ALIVE); 589 SchedulerWorker::InitialState::ALIVE);
565 590
566 // Verify that the initial thread priority is BACKGROUND (or NORMAL if thread 591 // Verify that the initial thread priority is BACKGROUND (or NORMAL if thread
567 // priority can't be increased). 592 // priority can't be increased).
568 worker->WakeUp(); 593 worker->WakeUp();
569 delegate_raw->WaitForPriorityVerifiedInGetWork(); 594 delegate_raw->WaitForPriorityVerifiedInGetWork();
570 595
571 // Verify that the thread priority is bumped to NORMAL during shutdown. 596 // Verify that the thread priority is bumped to NORMAL during shutdown.
572 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL); 597 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL);
573 task_tracker.SetHasShutdownStartedForTesting(); 598 task_tracker_.SetHasShutdownStartedForTesting();
574 worker->WakeUp(); 599 worker->WakeUp();
575 delegate_raw->WaitForPriorityVerifiedInGetWork(); 600 delegate_raw->WaitForPriorityVerifiedInGetWork();
576 601
577 worker->JoinForTesting(); 602 worker->JoinForTesting();
578 } 603 }
579 604
580 TEST(TaskSchedulerWorkerTest, BumpPriorityOfDetachedThreadDuringShutdown) { 605 TEST_F(TaskSchedulerWorkerTest, BumpPriorityOfDetachedThreadDuringShutdown) {
581 TaskTracker task_tracker;
582
583 std::unique_ptr<ExpectThreadPriorityDelegate> delegate( 606 std::unique_ptr<ExpectThreadPriorityDelegate> delegate(
584 new ExpectThreadPriorityDelegate); 607 new ExpectThreadPriorityDelegate);
585 ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); 608 ExpectThreadPriorityDelegate* delegate_raw = delegate.get();
586 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL); 609 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL);
587 610
588 // Create a DETACHED thread. 611 // Create a DETACHED thread.
589 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( 612 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create(
590 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, 613 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker_,
591 SchedulerWorker::InitialState::DETACHED); 614 SchedulerWorker::InitialState::DETACHED);
592 615
593 // Pretend that shutdown has started. 616 // Pretend that shutdown has started.
594 task_tracker.SetHasShutdownStartedForTesting(); 617 task_tracker_.SetHasShutdownStartedForTesting();
595 618
596 // Wake up the thread and verify that its priority is NORMAL when 619 // Wake up the thread and verify that its priority is NORMAL when
597 // OnMainEntry() and GetWork() are called. 620 // OnMainEntry() and GetWork() are called.
598 worker->WakeUp(); 621 worker->WakeUp();
599 delegate_raw->WaitForPriorityVerifiedInGetWork(); 622 delegate_raw->WaitForPriorityVerifiedInGetWork();
600 623
601 worker->JoinForTesting(); 624 worker->JoinForTesting();
602 } 625 }
603 626
604 } // namespace 627 } // namespace
605 } // namespace internal 628 } // namespace internal
606 } // namespace base 629 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698