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(); |