Index: base/task_scheduler/task_tracker_unittest.cc |
diff --git a/base/task_scheduler/task_tracker_unittest.cc b/base/task_scheduler/task_tracker_unittest.cc |
index 326f7aa02bc79602b34d665a2762e6e7965b7cf4..603bf73cd7fa26645a0677452ea7189ad363f18d 100644 |
--- a/base/task_scheduler/task_tracker_unittest.cc |
+++ b/base/task_scheduler/task_tracker_unittest.cc |
@@ -14,10 +14,12 @@ |
#include "base/macros.h" |
#include "base/memory/ptr_util.h" |
#include "base/memory/ref_counted.h" |
+#include "base/sequence_token.h" |
#include "base/sequenced_task_runner.h" |
#include "base/single_thread_task_runner.h" |
#include "base/synchronization/waitable_event.h" |
#include "base/task_scheduler/scheduler_lock.h" |
+#include "base/task_scheduler/sequence.h" |
#include "base/task_scheduler/task.h" |
#include "base/task_scheduler/task_traits.h" |
#include "base/task_scheduler/test_utils.h" |
@@ -36,6 +38,12 @@ namespace { |
constexpr size_t kLoadTestNumIterations = 100; |
+scoped_refptr<Sequence> CreateSequenceWithTask(std::unique_ptr<Task> task) { |
+ scoped_refptr<Sequence> sequence(new Sequence); |
+ sequence->PushTask(std::move(task)); |
+ return sequence; |
+} |
+ |
// Calls TaskTracker::Shutdown() asynchronously. |
class ThreadCallingShutdown : public SimpleThread { |
public: |
@@ -69,12 +77,12 @@ class ThreadPostingAndRunningTask : public SimpleThread { |
}; |
ThreadPostingAndRunningTask(TaskTracker* tracker, |
- const Task* task, |
+ scoped_refptr<Sequence> sequence, |
Action action, |
bool expect_post_succeeds) |
: SimpleThread("ThreadPostingAndRunningTask"), |
tracker_(tracker), |
- task_(task), |
+ sequence_(std::move(sequence)), |
action_(action), |
expect_post_succeeds_(expect_post_succeeds) {} |
@@ -82,17 +90,17 @@ class ThreadPostingAndRunningTask : public SimpleThread { |
void Run() override { |
bool post_succeeded = true; |
if (action_ == Action::WILL_POST || action_ == Action::WILL_POST_AND_RUN) { |
- post_succeeded = tracker_->WillPostTask(task_); |
+ post_succeeded = tracker_->WillPostTask(sequence_->PeekTask()); |
EXPECT_EQ(expect_post_succeeds_, post_succeeded); |
} |
if (post_succeeded && |
(action_ == Action::RUN || action_ == Action::WILL_POST_AND_RUN)) { |
- tracker_->RunTask(task_); |
+ tracker_->RunNextTaskInSequence(sequence_.get()); |
} |
} |
TaskTracker* const tracker_; |
- const Task* const task_; |
+ const scoped_refptr<Sequence> sequence_; |
const Action action_; |
const bool expect_post_succeeds_; |
@@ -195,7 +203,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunBeforeShutdown) { |
// Run the task. |
EXPECT_EQ(0U, NumTasksExecuted()); |
- tracker_.RunTask(task.get()); |
+ tracker_.RunNextTaskInSequence(CreateSequenceWithTask(std::move(task)).get()); |
EXPECT_EQ(1U, NumTasksExecuted()); |
// Shutdown() shouldn't block. |
@@ -215,8 +223,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) { |
// Run the task asynchronouly. |
ThreadPostingAndRunningTask thread_running_task( |
- &tracker_, blocked_task.get(), ThreadPostingAndRunningTask::Action::RUN, |
- false); |
+ &tracker_, CreateSequenceWithTask(std::move(blocked_task)), |
+ ThreadPostingAndRunningTask::Action::RUN, false); |
thread_running_task.Start(); |
// Initiate shutdown while the task is running. |
@@ -257,13 +265,14 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunDuringShutdown) { |
// Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it |
// should be discarded. |
EXPECT_EQ(0U, NumTasksExecuted()); |
- tracker_.RunTask(task.get()); |
+ tracker_.RunNextTaskInSequence(CreateSequenceWithTask(std::move(task)).get()); |
EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 1U : 0U, |
NumTasksExecuted()); |
VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
// Unblock shutdown by running the remaining BLOCK_SHUTDOWN task. |
- tracker_.RunTask(block_shutdown_task.get()); |
+ tracker_.RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(block_shutdown_task)).get()); |
EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, |
NumTasksExecuted()); |
WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
@@ -282,7 +291,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) { |
VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
// Run the task to unblock shutdown. |
- tracker_.RunTask(task.get()); |
+ tracker_.RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(task)).get()); |
EXPECT_EQ(1U, NumTasksExecuted()); |
WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
@@ -293,7 +303,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) { |
WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
// The task shouldn't be allowed to run after shutdown. |
- tracker_.RunTask(task.get()); |
+ tracker_.RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(task)).get()); |
EXPECT_EQ(0U, NumTasksExecuted()); |
} |
} |
@@ -316,7 +327,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) { |
// Run the BLOCK_SHUTDOWN task. |
EXPECT_EQ(0U, NumTasksExecuted()); |
- tracker_.RunTask(task.get()); |
+ tracker_.RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(task)).get()); |
EXPECT_EQ(1U, NumTasksExecuted()); |
} else { |
// It shouldn't be allowed to post a non BLOCK_SHUTDOWN task. |
@@ -328,7 +340,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) { |
// Unblock shutdown by running |block_shutdown_task|. |
VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
- tracker_.RunTask(block_shutdown_task.get()); |
+ tracker_.RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(block_shutdown_task)).get()); |
EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, |
NumTasksExecuted()); |
WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
@@ -354,9 +367,10 @@ TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) { |
(GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN); |
TaskTracker tracker; |
- Task task(FROM_HERE, Bind(&ThreadRestrictions::AssertSingletonAllowed), |
- TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); |
- EXPECT_TRUE(tracker.WillPostTask(&task)); |
+ std::unique_ptr<Task> task( |
+ new Task(FROM_HERE, Bind(&ThreadRestrictions::AssertSingletonAllowed), |
+ TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
+ EXPECT_TRUE(tracker.WillPostTask(task.get())); |
// Set the singleton allowed bit to the opposite of what it is expected to be |
// when |tracker| runs |task| to verify that |tracker| actually sets the |
@@ -365,23 +379,31 @@ TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) { |
// Running the task should fail iff the task isn't allowed to use singletons. |
if (can_use_singletons) { |
- tracker.RunTask(&task); |
+ tracker.RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(task)).get()); |
} else { |
- EXPECT_DCHECK_DEATH({ tracker.RunTask(&task); }, ""); |
+ EXPECT_DCHECK_DEATH( |
+ { |
+ tracker.RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(task)).get()); |
+ }, |
+ ""); |
} |
} |
-static void RunTaskRunnerHandleVerificationTask(TaskTracker* tracker, |
- const Task* verify_task) { |
+static void RunTaskRunnerHandleVerificationTask( |
+ TaskTracker* tracker, |
+ std::unique_ptr<Task> verify_task) { |
// Pretend |verify_task| is posted to respect TaskTracker's contract. |
- EXPECT_TRUE(tracker->WillPostTask(verify_task)); |
+ EXPECT_TRUE(tracker->WillPostTask(verify_task.get())); |
// Confirm that the test conditions are right (no TaskRunnerHandles set |
// already). |
EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
- tracker->RunTask(verify_task); |
+ tracker->RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(verify_task)).get()); |
// TaskRunnerHandle state is reset outside of task's scope. |
EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
@@ -400,7 +422,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, TaskRunnerHandleIsNotSetOnParallel) { |
new Task(FROM_HERE, Bind(&VerifyNoTaskRunnerHandle), |
TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
- RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); |
+ RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
} |
static void VerifySequencedTaskRunnerHandle( |
@@ -423,7 +445,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, |
TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
verify_task->sequenced_task_runner_ref = test_task_runner; |
- RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); |
+ RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
} |
static void VerifyThreadTaskRunnerHandle( |
@@ -448,7 +470,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, |
TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
verify_task->single_thread_task_runner_ref = test_task_runner; |
- RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); |
+ RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
} |
INSTANTIATE_TEST_CASE_P( |
@@ -464,27 +486,48 @@ INSTANTIATE_TEST_CASE_P( |
TaskSchedulerTaskTrackerTest, |
::testing::Values(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+namespace { |
+ |
+void ExpectSequenceToken(SequenceToken sequence_token) { |
+ EXPECT_EQ(sequence_token, SequenceToken::GetForCurrentThread()); |
+} |
+ |
+} // namespace |
+ |
+// Verify that SequenceToken::GetForCurrentThread() returns the Sequence's token |
+// when a Task runs. |
+TEST_F(TaskSchedulerTaskTrackerTest, CurrentSequenceToken) { |
+ scoped_refptr<Sequence> sequence(new Sequence); |
+ sequence->PushTask(WrapUnique( |
+ new Task(FROM_HERE, Bind(&ExpectSequenceToken, sequence->token()), |
+ TaskTraits(), TimeDelta()))); |
+ tracker_.WillPostTask(sequence->PeekTask()); |
+ |
+ EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
+ tracker_.RunNextTaskInSequence(sequence.get()); |
+ EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
+} |
+ |
TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
// Post and run tasks asynchronously. |
- std::vector<std::unique_ptr<Task>> tasks; |
std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
- tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), |
ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
threads.back()->Start(); |
- tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), |
ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
threads.back()->Start(); |
- tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), |
ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
threads.back()->Start(); |
} |
@@ -502,25 +545,28 @@ TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
TEST_F(TaskSchedulerTaskTrackerTest, |
LoadWillPostBeforeShutdownAndRunDuringShutdown) { |
// Post tasks asynchronously. |
- std::vector<std::unique_ptr<Task>> tasks; |
+ std::vector<scoped_refptr<Sequence>> sequences; |
std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads; |
for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
- tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ sequences.push_back(CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN))); |
post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, sequences.back(), |
ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
post_threads.back()->Start(); |
- tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ sequences.push_back(CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN))); |
post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, sequences.back(), |
ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
post_threads.back()->Start(); |
- tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ sequences.push_back(CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN))); |
post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, sequences.back(), |
ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
post_threads.back()->Start(); |
} |
@@ -534,10 +580,9 @@ TEST_F(TaskSchedulerTaskTrackerTest, |
// Run tasks asynchronously. |
std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; |
- for (const auto& task : tasks) { |
+ for (const auto& sequence : sequences) { |
run_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, task.get(), ThreadPostingAndRunningTask::Action::RUN, |
- false))); |
+ &tracker_, sequence, ThreadPostingAndRunningTask::Action::RUN, false))); |
run_threads.back()->Start(); |
} |
@@ -561,25 +606,24 @@ TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { |
CallShutdownAsync(); |
// Post and run tasks asynchronously. |
- std::vector<std::unique_ptr<Task>> tasks; |
std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
- tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), |
ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); |
threads.back()->Start(); |
- tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), |
ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); |
threads.back()->Start(); |
- tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
- &tracker_, tasks.back().get(), |
+ &tracker_, CreateSequenceWithTask( |
+ CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), |
ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
threads.back()->Start(); |
} |
@@ -594,7 +638,8 @@ TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { |
VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
// Unblock shutdown by running |block_shutdown_task|. |
- tracker_.RunTask(block_shutdown_task.get()); |
+ tracker_.RunNextTaskInSequence( |
+ CreateSequenceWithTask(std::move(block_shutdown_task)).get()); |
EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); |
WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
} |