 Chromium Code Reviews
 Chromium Code Reviews Issue 2686593003:
  DESIGN DISCUSSION ONLY Task Scheduler Single Thread Task Runner Manager for Dedicated Threads per S…  (Closed)
    
  
    Issue 2686593003:
  DESIGN DISCUSSION ONLY Task Scheduler Single Thread Task Runner Manager for Dedicated Threads per S…  (Closed) 
  | Index: base/task_scheduler/scheduler_worker_unittest.cc | 
| diff --git a/base/task_scheduler/scheduler_worker_unittest.cc b/base/task_scheduler/scheduler_worker_unittest.cc | 
| index b65d50c07c3fb5db64ba8df08031bc6934ef10a5..0d02021f10e9267baa9faff9f94b36bf11d7b4f3 100644 | 
| --- a/base/task_scheduler/scheduler_worker_unittest.cc | 
| +++ b/base/task_scheduler/scheduler_worker_unittest.cc | 
| @@ -19,6 +19,7 @@ | 
| #include "base/task_scheduler/sequence.h" | 
| #include "base/task_scheduler/task.h" | 
| #include "base/task_scheduler/task_tracker.h" | 
| +#include "base/test/test_timeouts.h" | 
| #include "base/threading/platform_thread.h" | 
| #include "base/time/time.h" | 
| #include "build/build_config.h" | 
| @@ -355,16 +356,13 @@ namespace { | 
| class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate { | 
| public: | 
| - ControllableDetachDelegate(TaskTracker* task_tracker) | 
| - : task_tracker_(task_tracker), | 
| - work_processed_(WaitableEvent::ResetPolicy::MANUAL, | 
| + ControllableDetachDelegate() | 
| + : work_processed_(WaitableEvent::ResetPolicy::MANUAL, | 
| WaitableEvent::InitialState::NOT_SIGNALED), | 
| detach_requested_(WaitableEvent::ResetPolicy::MANUAL, | 
| WaitableEvent::InitialState::NOT_SIGNALED), | 
| detached_(WaitableEvent::ResetPolicy::MANUAL, | 
| - WaitableEvent::InitialState::NOT_SIGNALED) { | 
| - EXPECT_TRUE(task_tracker_); | 
| - } | 
| + WaitableEvent::InitialState::NOT_SIGNALED) {} | 
| ~ControllableDetachDelegate() override = default; | 
| @@ -383,7 +381,7 @@ class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate { | 
| std::unique_ptr<Task> task(new Task( | 
| FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), | 
| TaskTraits(), TimeDelta())); | 
| - EXPECT_TRUE(task_tracker_->WillPostTask(task.get())); | 
| + EXPECT_TRUE(task_tracker_.WillPostTask(task.get())); | 
| sequence->PushTask(std::move(task)); | 
| return sequence; | 
| } | 
| @@ -419,8 +417,12 @@ class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate { | 
| void set_can_detach(bool can_detach) { can_detach_ = can_detach; } | 
| + // This delegate owns the TaskTracker because during detachment, threads may | 
| + // outlive the test case. | 
| 
fdoray
2017/02/08 17:59:02
I think this is no longer true if you do https://c
 
robliao
2017/02/11 02:13:34
That is true. Removed.
 | 
| + TaskTracker* task_tracker() { return &task_tracker_; } | 
| + | 
| private: | 
| - TaskTracker* const task_tracker_; | 
| + TaskTracker task_tracker_; | 
| bool work_requested_ = false; | 
| bool can_detach_ = false; | 
| WaitableEvent work_processed_; | 
| @@ -433,16 +435,14 @@ class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate { | 
| } // namespace | 
| TEST(TaskSchedulerWorkerTest, WorkerDetaches) { | 
| - TaskTracker task_tracker; | 
| // Will be owned by SchedulerWorker. | 
| ControllableDetachDelegate* delegate = | 
| - new StrictMock<ControllableDetachDelegate>(&task_tracker); | 
| + new StrictMock<ControllableDetachDelegate>(); | 
| delegate->set_can_detach(true); | 
| EXPECT_CALL(*delegate, OnMainEntry(_)); | 
| - std::unique_ptr<SchedulerWorker> worker = | 
| - SchedulerWorker::Create( | 
| - ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, | 
| - SchedulerWorker::InitialState::ALIVE); | 
| + std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( | 
| + ThreadPriority::NORMAL, WrapUnique(delegate), delegate->task_tracker(), | 
| + SchedulerWorker::InitialState::ALIVE); | 
| worker->WakeUp(); | 
| delegate->WaitForWorkToRun(); | 
| Mock::VerifyAndClear(delegate); | 
| @@ -451,17 +451,31 @@ TEST(TaskSchedulerWorkerTest, WorkerDetaches) { | 
| ASSERT_FALSE(worker->ThreadAliveForTesting()); | 
| } | 
| +TEST(TaskSchedulerWorkerTest, WorkerDetachesAndSelfDestroys) { | 
| + // This test shouldn't crash or leak resources. | 
| + // Will be owned by SchedulerWorker. | 
| + ControllableDetachDelegate* delegate = | 
| + new StrictMock<ControllableDetachDelegate>(); | 
| + delegate->set_can_detach(true); | 
| + EXPECT_CALL(*delegate, OnMainEntry(_)); | 
| + std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( | 
| + ThreadPriority::NORMAL, WrapUnique(delegate), delegate->task_tracker(), | 
| + SchedulerWorker::InitialState::ALIVE); | 
| + worker->WakeUp(); | 
| + SchedulerWorker::DestroyAfterDetachment(std::move(worker)); | 
| + // Give a chance for the other thread to clean up. | 
| 
fdoray
2017/02/08 17:59:02
You could signal an event in ~ControllableDetachDe
 
robliao
2017/02/11 02:13:34
I went with a refcounted event instead.
 | 
| + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 
| +} | 
| + | 
| TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) { | 
| - TaskTracker task_tracker; | 
| // Will be owned by SchedulerWorker. | 
| ControllableDetachDelegate* delegate = | 
| - new StrictMock<ControllableDetachDelegate>(&task_tracker); | 
| + new StrictMock<ControllableDetachDelegate>(); | 
| delegate->set_can_detach(true); | 
| EXPECT_CALL(*delegate, OnMainEntry(_)); | 
| - std::unique_ptr<SchedulerWorker> worker = | 
| - SchedulerWorker::Create( | 
| - ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, | 
| - SchedulerWorker::InitialState::ALIVE); | 
| + std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( | 
| + ThreadPriority::NORMAL, WrapUnique(delegate), delegate->task_tracker(), | 
| + SchedulerWorker::InitialState::ALIVE); | 
| worker->WakeUp(); | 
| delegate->WaitForWorkToRun(); | 
| Mock::VerifyAndClear(delegate); | 
| @@ -484,14 +498,12 @@ TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) { | 
| } | 
| TEST(TaskSchedulerWorkerTest, CreateDetached) { | 
| - TaskTracker task_tracker; | 
| // Will be owned by SchedulerWorker. | 
| ControllableDetachDelegate* delegate = | 
| - new StrictMock<ControllableDetachDelegate>(&task_tracker); | 
| - std::unique_ptr<SchedulerWorker> worker = | 
| - SchedulerWorker::Create( | 
| - ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, | 
| - SchedulerWorker::InitialState::DETACHED); | 
| + new StrictMock<ControllableDetachDelegate>(); | 
| + std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( | 
| + ThreadPriority::NORMAL, WrapUnique(delegate), delegate->task_tracker(), | 
| + SchedulerWorker::InitialState::DETACHED); | 
| ASSERT_FALSE(worker->ThreadAliveForTesting()); | 
| EXPECT_CALL(*delegate, OnMainEntry(worker.get())); | 
| worker->WakeUp(); |