| OLD | NEW |
| 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> |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 TaskSchedulerWorkerTest, | 345 TaskSchedulerWorkerTest, |
| 346 ::testing::Values(1)); | 346 ::testing::Values(1)); |
| 347 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, | 347 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, |
| 348 TaskSchedulerWorkerTest, | 348 TaskSchedulerWorkerTest, |
| 349 ::testing::Values(2)); | 349 ::testing::Values(2)); |
| 350 | 350 |
| 351 namespace { | 351 namespace { |
| 352 | 352 |
| 353 class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate { | 353 class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate { |
| 354 public: | 354 public: |
| 355 ControllableDetachDelegate() | 355 ControllableDetachDelegate(TaskTracker* task_tracker) |
| 356 : work_processed_(WaitableEvent::ResetPolicy::MANUAL, | 356 : task_tracker_(task_tracker), |
| 357 work_processed_(WaitableEvent::ResetPolicy::MANUAL, |
| 357 WaitableEvent::InitialState::NOT_SIGNALED), | 358 WaitableEvent::InitialState::NOT_SIGNALED), |
| 358 detach_requested_(WaitableEvent::ResetPolicy::MANUAL, | 359 detach_requested_(WaitableEvent::ResetPolicy::MANUAL, |
| 359 WaitableEvent::InitialState::NOT_SIGNALED) {} | 360 WaitableEvent::InitialState::NOT_SIGNALED) { |
| 361 EXPECT_TRUE(task_tracker_); |
| 362 } |
| 360 | 363 |
| 361 ~ControllableDetachDelegate() override = default; | 364 ~ControllableDetachDelegate() override = default; |
| 362 | 365 |
| 363 // SchedulerWorker::Delegate: | 366 // SchedulerWorker::Delegate: |
| 364 MOCK_METHOD2(OnMainEntry, | 367 MOCK_METHOD2(OnMainEntry, |
| 365 void(SchedulerWorker* worker, const TimeDelta& detach_duration)); | 368 void(SchedulerWorker* worker, const TimeDelta& detach_duration)); |
| 366 | 369 |
| 367 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) | 370 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) |
| 368 override { | 371 override { |
| 369 // Sends one item of work to signal |work_processed_|. On subsequent calls, | 372 // Sends one item of work to signal |work_processed_|. On subsequent calls, |
| 370 // sends nullptr to indicate there's no more work to be done. | 373 // sends nullptr to indicate there's no more work to be done. |
| 371 if (work_requested_) | 374 if (work_requested_) |
| 372 return nullptr; | 375 return nullptr; |
| 373 | 376 |
| 374 work_requested_ = true; | 377 work_requested_ = true; |
| 375 scoped_refptr<Sequence> sequence(new Sequence); | 378 scoped_refptr<Sequence> sequence(new Sequence); |
| 376 std::unique_ptr<Task> task(new Task( | 379 std::unique_ptr<Task> task(new Task( |
| 377 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), | 380 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), |
| 378 TaskTraits(), TimeDelta())); | 381 TaskTraits(), TimeDelta())); |
| 382 EXPECT_TRUE(task_tracker_->WillPostTask(task.get())); |
| 379 sequence->PushTask(std::move(task)); | 383 sequence->PushTask(std::move(task)); |
| 380 return sequence; | 384 return sequence; |
| 381 } | 385 } |
| 382 | 386 |
| 383 void DidRunTask(const Task* task, const TimeDelta& task_latency) override {} | 387 void DidRunTask(const Task* task, const TimeDelta& task_latency) override {} |
| 384 | 388 |
| 385 bool CanDetach(SchedulerWorker* worker) override { | 389 bool CanDetach(SchedulerWorker* worker) override { |
| 386 detach_requested_.Signal(); | 390 detach_requested_.Signal(); |
| 387 return can_detach_; | 391 return can_detach_; |
| 388 } | 392 } |
| 389 | 393 |
| 390 void WaitForWorkToRun() { | 394 void WaitForWorkToRun() { |
| 391 work_processed_.Wait(); | 395 work_processed_.Wait(); |
| 392 } | 396 } |
| 393 | 397 |
| 394 void WaitForDetachRequest() { | 398 void WaitForDetachRequest() { |
| 395 detach_requested_.Wait(); | 399 detach_requested_.Wait(); |
| 396 } | 400 } |
| 397 | 401 |
| 398 void ResetState() { | 402 void ResetState() { |
| 399 work_requested_ = false; | 403 work_requested_ = false; |
| 400 work_processed_.Reset(); | 404 work_processed_.Reset(); |
| 401 detach_requested_.Reset(); | 405 detach_requested_.Reset(); |
| 402 } | 406 } |
| 403 | 407 |
| 404 void set_can_detach(bool can_detach) { can_detach_ = can_detach; } | 408 void set_can_detach(bool can_detach) { can_detach_ = can_detach; } |
| 405 | 409 |
| 406 private: | 410 private: |
| 411 TaskTracker* const task_tracker_; |
| 407 bool work_requested_ = false; | 412 bool work_requested_ = false; |
| 408 bool can_detach_ = false; | 413 bool can_detach_ = false; |
| 409 WaitableEvent work_processed_; | 414 WaitableEvent work_processed_; |
| 410 WaitableEvent detach_requested_; | 415 WaitableEvent detach_requested_; |
| 411 | 416 |
| 412 DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate); | 417 DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate); |
| 413 }; | 418 }; |
| 414 | 419 |
| 415 } // namespace | 420 } // namespace |
| 416 | 421 |
| 417 TEST(TaskSchedulerWorkerTest, WorkerDetaches) { | 422 TEST(TaskSchedulerWorkerTest, WorkerDetaches) { |
| 418 TaskTracker task_tracker; | 423 TaskTracker task_tracker; |
| 419 // Will be owned by SchedulerWorker. | 424 // Will be owned by SchedulerWorker. |
| 420 ControllableDetachDelegate* delegate = | 425 ControllableDetachDelegate* delegate = |
| 421 new StrictMock<ControllableDetachDelegate>; | 426 new StrictMock<ControllableDetachDelegate>(&task_tracker); |
| 422 delegate->set_can_detach(true); | 427 delegate->set_can_detach(true); |
| 423 EXPECT_CALL(*delegate, OnMainEntry(_, TimeDelta::Max())); | 428 EXPECT_CALL(*delegate, OnMainEntry(_, TimeDelta::Max())); |
| 424 std::unique_ptr<SchedulerWorker> worker = | 429 std::unique_ptr<SchedulerWorker> worker = |
| 425 SchedulerWorker::Create( | 430 SchedulerWorker::Create( |
| 426 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, | 431 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, |
| 427 SchedulerWorker::InitialState::ALIVE); | 432 SchedulerWorker::InitialState::ALIVE); |
| 428 worker->WakeUp(); | 433 worker->WakeUp(); |
| 429 delegate->WaitForWorkToRun(); | 434 delegate->WaitForWorkToRun(); |
| 430 Mock::VerifyAndClear(delegate); | 435 Mock::VerifyAndClear(delegate); |
| 431 delegate->WaitForDetachRequest(); | 436 delegate->WaitForDetachRequest(); |
| 432 // Sleep to give a chance for the detach to happen. A yield is too short. | 437 // Sleep to give a chance for the detach to happen. A yield is too short. |
| 433 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); | 438 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); |
| 434 ASSERT_FALSE(worker->ThreadAliveForTesting()); | 439 ASSERT_FALSE(worker->ThreadAliveForTesting()); |
| 435 } | 440 } |
| 436 | 441 |
| 437 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) { | 442 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) { |
| 438 TaskTracker task_tracker; | 443 TaskTracker task_tracker; |
| 439 // Will be owned by SchedulerWorker. | 444 // Will be owned by SchedulerWorker. |
| 440 ControllableDetachDelegate* delegate = | 445 ControllableDetachDelegate* delegate = |
| 441 new StrictMock<ControllableDetachDelegate>; | 446 new StrictMock<ControllableDetachDelegate>(&task_tracker); |
| 442 delegate->set_can_detach(true); | 447 delegate->set_can_detach(true); |
| 443 EXPECT_CALL(*delegate, OnMainEntry(_, TimeDelta::Max())); | 448 EXPECT_CALL(*delegate, OnMainEntry(_, TimeDelta::Max())); |
| 444 std::unique_ptr<SchedulerWorker> worker = | 449 std::unique_ptr<SchedulerWorker> worker = |
| 445 SchedulerWorker::Create( | 450 SchedulerWorker::Create( |
| 446 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, | 451 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, |
| 447 SchedulerWorker::InitialState::ALIVE); | 452 SchedulerWorker::InitialState::ALIVE); |
| 448 worker->WakeUp(); | 453 worker->WakeUp(); |
| 449 delegate->WaitForWorkToRun(); | 454 delegate->WaitForWorkToRun(); |
| 450 Mock::VerifyAndClear(delegate); | 455 Mock::VerifyAndClear(delegate); |
| 451 delegate->WaitForDetachRequest(); | 456 delegate->WaitForDetachRequest(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 464 delegate->WaitForDetachRequest(); | 469 delegate->WaitForDetachRequest(); |
| 465 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); | 470 PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); |
| 466 ASSERT_TRUE(worker->ThreadAliveForTesting()); | 471 ASSERT_TRUE(worker->ThreadAliveForTesting()); |
| 467 worker->JoinForTesting(); | 472 worker->JoinForTesting(); |
| 468 } | 473 } |
| 469 | 474 |
| 470 TEST(TaskSchedulerWorkerTest, CreateDetached) { | 475 TEST(TaskSchedulerWorkerTest, CreateDetached) { |
| 471 TaskTracker task_tracker; | 476 TaskTracker task_tracker; |
| 472 // Will be owned by SchedulerWorker. | 477 // Will be owned by SchedulerWorker. |
| 473 ControllableDetachDelegate* delegate = | 478 ControllableDetachDelegate* delegate = |
| 474 new StrictMock<ControllableDetachDelegate>; | 479 new StrictMock<ControllableDetachDelegate>(&task_tracker); |
| 475 std::unique_ptr<SchedulerWorker> worker = | 480 std::unique_ptr<SchedulerWorker> worker = |
| 476 SchedulerWorker::Create( | 481 SchedulerWorker::Create( |
| 477 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, | 482 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, |
| 478 SchedulerWorker::InitialState::DETACHED); | 483 SchedulerWorker::InitialState::DETACHED); |
| 479 ASSERT_FALSE(worker->ThreadAliveForTesting()); | 484 ASSERT_FALSE(worker->ThreadAliveForTesting()); |
| 480 EXPECT_CALL(*delegate, OnMainEntry(worker.get(), TimeDelta::Max())); | 485 EXPECT_CALL(*delegate, OnMainEntry(worker.get(), TimeDelta::Max())); |
| 481 worker->WakeUp(); | 486 worker->WakeUp(); |
| 482 delegate->WaitForWorkToRun(); | 487 delegate->WaitForWorkToRun(); |
| 483 Mock::VerifyAndClear(delegate); | 488 Mock::VerifyAndClear(delegate); |
| 484 delegate->WaitForDetachRequest(); | 489 delegate->WaitForDetachRequest(); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 // OnMainEntry() and GetWork() are called. | 590 // OnMainEntry() and GetWork() are called. |
| 586 worker->WakeUp(); | 591 worker->WakeUp(); |
| 587 delegate_raw->WaitForPriorityVerifiedInGetWork(); | 592 delegate_raw->WaitForPriorityVerifiedInGetWork(); |
| 588 | 593 |
| 589 worker->JoinForTesting(); | 594 worker->JoinForTesting(); |
| 590 } | 595 } |
| 591 | 596 |
| 592 } // namespace | 597 } // namespace |
| 593 } // namespace internal | 598 } // namespace internal |
| 594 } // namespace base | 599 } // namespace base |
| OLD | NEW |