blob: 8afd5a18d7a7f9f2896799593ebe4676aa94bad7 [file] [log] [blame]
[email protected]5761ab9c2012-02-04 16:44:531// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]098def22012-01-01 05:42:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]89993aee2012-04-11 08:10:115#include "base/threading/sequenced_worker_pool.h"
6
avi9ceb8b82015-12-24 21:53:597#include <stddef.h>
8
[email protected]098def22012-01-01 05:42:349#include <algorithm>
dcheng093de9b2016-04-04 21:25:5110#include <memory>
[email protected]098def22012-01-01 05:42:3411
12#include "base/bind.h"
[email protected]71b18fb2012-03-06 14:17:3413#include "base/compiler_specific.h"
avi9ceb8b82015-12-24 21:53:5914#include "base/macros.h"
[email protected]098def22012-01-01 05:42:3415#include "base/memory/ref_counted.h"
[email protected]495cad92013-07-18 08:12:4016#include "base/message_loop/message_loop.h"
thestig6c335d42015-12-07 18:25:3417#include "base/stl_util.h"
[email protected]098def22012-01-01 05:42:3418#include "base/synchronization/condition_variable.h"
19#include "base/synchronization/lock.h"
fdoray37e794792016-09-16 23:19:5020#include "base/task_scheduler/scheduler_worker_pool_params.h"
21#include "base/task_scheduler/task_scheduler.h"
[email protected]89993aee2012-04-11 08:10:1122#include "base/test/sequenced_task_runner_test_template.h"
[email protected]8f9a3a52013-06-28 15:14:1823#include "base/test/sequenced_worker_pool_owner.h"
[email protected]c8cae7c2012-03-09 06:20:1824#include "base/test/task_runner_test_template.h"
[email protected]44024782013-02-26 22:59:5025#include "base/test/test_timeouts.h"
[email protected]098def22012-01-01 05:42:3426#include "base/threading/platform_thread.h"
[email protected]8f9a3a52013-06-28 15:14:1827#include "base/time/time.h"
[email protected]098def22012-01-01 05:42:3428#include "testing/gtest/include/gtest/gtest.h"
29
30namespace base {
31
32// IMPORTANT NOTE:
33//
34// Many of these tests have failure modes where they'll hang forever. These
[email protected]4f60d802013-04-18 05:41:2335// tests should not be flaky, and hanging indicates a type of failure. Do not
[email protected]098def22012-01-01 05:42:3436// mark as flaky if they're hanging, it's likely an actual bug.
37
38namespace {
39
40const size_t kNumWorkerThreads = 3;
41
42// Allows a number of threads to all be blocked on the same event, and
43// provides a way to unblock a certain number of them.
44class ThreadBlocker {
45 public:
[email protected]a9aaa9d12012-04-25 00:42:5146 ThreadBlocker() : lock_(), cond_var_(&lock_), unblock_counter_(0) {}
[email protected]098def22012-01-01 05:42:3447
48 void Block() {
49 {
50 base::AutoLock lock(lock_);
51 while (unblock_counter_ == 0)
52 cond_var_.Wait();
53 unblock_counter_--;
54 }
55 cond_var_.Signal();
56 }
57
58 void Unblock(size_t count) {
59 {
60 base::AutoLock lock(lock_);
danakj94219a212015-03-09 22:27:2561 DCHECK_EQ(unblock_counter_, 0u);
[email protected]098def22012-01-01 05:42:3462 unblock_counter_ = count;
63 }
64 cond_var_.Signal();
65 }
66
67 private:
68 base::Lock lock_;
69 base::ConditionVariable cond_var_;
70
71 size_t unblock_counter_;
72};
73
erikcheneae82f22015-02-26 19:37:4274class DestructionDeadlockChecker
75 : public base::RefCountedThreadSafe<DestructionDeadlockChecker> {
76 public:
vmpstr82b0c16d2016-03-18 19:17:2877 explicit DestructionDeadlockChecker(scoped_refptr<SequencedWorkerPool> pool)
78 : pool_(std::move(pool)) {}
erikcheneae82f22015-02-26 19:37:4279
80 protected:
81 virtual ~DestructionDeadlockChecker() {
82 // This method should not deadlock.
Yeola89b2662017-07-25 17:09:1083 pool_->RunsTasksInCurrentSequence();
erikcheneae82f22015-02-26 19:37:4284 }
85
86 private:
87 scoped_refptr<SequencedWorkerPool> pool_;
88 friend class base::RefCountedThreadSafe<DestructionDeadlockChecker>;
89};
90
[email protected]098def22012-01-01 05:42:3491class TestTracker : public base::RefCountedThreadSafe<TestTracker> {
92 public:
93 TestTracker()
94 : lock_(),
95 cond_var_(&lock_),
96 started_events_(0) {
97 }
98
99 // Each of these tasks appends the argument to the complete sequence vector
100 // so calling code can see what order they finished in.
101 void FastTask(int id) {
102 SignalWorkerDone(id);
103 }
[email protected]a9aaa9d12012-04-25 00:42:51104
[email protected]098def22012-01-01 05:42:34105 void SlowTask(int id) {
[email protected]5761ab9c2012-02-04 16:44:53106 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
[email protected]098def22012-01-01 05:42:34107 SignalWorkerDone(id);
108 }
109
110 void BlockTask(int id, ThreadBlocker* blocker) {
111 // Note that this task has started and signal anybody waiting for that
112 // to happen.
113 {
114 base::AutoLock lock(lock_);
115 started_events_++;
116 }
117 cond_var_.Signal();
118
119 blocker->Block();
120 SignalWorkerDone(id);
121 }
122
[email protected]13ecb5e92013-03-07 01:35:37123 void PostAdditionalTasks(
124 int id, SequencedWorkerPool* pool,
125 bool expected_return_value) {
[email protected]270f2cf2012-12-19 01:56:37126 Closure fast_task = base::Bind(&TestTracker::FastTask, this, 100);
[email protected]13ecb5e92013-03-07 01:35:37127 EXPECT_EQ(expected_return_value,
128 pool->PostWorkerTaskWithShutdownBehavior(
129 FROM_HERE, fast_task,
130 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
131 EXPECT_EQ(expected_return_value,
132 pool->PostWorkerTaskWithShutdownBehavior(
133 FROM_HERE, fast_task,
134 SequencedWorkerPool::SKIP_ON_SHUTDOWN));
[email protected]270f2cf2012-12-19 01:56:37135 pool->PostWorkerTaskWithShutdownBehavior(
136 FROM_HERE, fast_task,
137 SequencedWorkerPool::BLOCK_SHUTDOWN);
138 SignalWorkerDone(id);
139 }
140
erikcheneae82f22015-02-26 19:37:42141 // This task posts itself back onto the SequencedWorkerPool before it
142 // finishes running. Each instance of the task maintains a strong reference
143 // to a DestructionDeadlockChecker. The DestructionDeadlockChecker is only
144 // destroyed when the task is destroyed without being run, which only happens
145 // during destruction of the SequencedWorkerPool.
146 void PostRepostingTask(
147 const scoped_refptr<SequencedWorkerPool>& pool,
148 const scoped_refptr<DestructionDeadlockChecker>& checker) {
149 Closure reposting_task =
150 base::Bind(&TestTracker::PostRepostingTask, this, pool, checker);
151 pool->PostWorkerTaskWithShutdownBehavior(
152 FROM_HERE, reposting_task, SequencedWorkerPool::SKIP_ON_SHUTDOWN);
153 }
154
erikchen19249bcc2015-03-13 22:57:37155 // This task reposts itself back onto the SequencedWorkerPool before it
156 // finishes running.
157 void PostRepostingBlockingTask(
158 const scoped_refptr<SequencedWorkerPool>& pool,
159 const SequencedWorkerPool::SequenceToken& token) {
160 Closure reposting_task =
161 base::Bind(&TestTracker::PostRepostingBlockingTask, this, pool, token);
162 pool->PostSequencedWorkerTaskWithShutdownBehavior(token,
163 FROM_HERE, reposting_task, SequencedWorkerPool::BLOCK_SHUTDOWN);
164 }
165
erikchen8982d902015-03-31 01:06:46166 void PostBlockingTaskThenUnblockThreads(
167 const scoped_refptr<SequencedWorkerPool>& pool,
168 ThreadBlocker* blocker,
169 size_t threads_to_wake) {
170 Closure arbitrary_task = base::Bind(&TestTracker::FastTask, this, 0);
171 pool->PostWorkerTaskWithShutdownBehavior(
172 FROM_HERE, arbitrary_task, SequencedWorkerPool::BLOCK_SHUTDOWN);
173 blocker->Unblock(threads_to_wake);
174 }
175
[email protected]098def22012-01-01 05:42:34176 // Waits until the given number of tasks have started executing.
177 void WaitUntilTasksBlocked(size_t count) {
178 {
179 base::AutoLock lock(lock_);
180 while (started_events_ < count)
181 cond_var_.Wait();
182 }
183 cond_var_.Signal();
184 }
185
186 // Blocks the current thread until at least the given number of tasks are in
187 // the completed vector, and then returns a copy.
188 std::vector<int> WaitUntilTasksComplete(size_t num_tasks) {
189 std::vector<int> ret;
190 {
191 base::AutoLock lock(lock_);
192 while (complete_sequence_.size() < num_tasks)
193 cond_var_.Wait();
194 ret = complete_sequence_;
195 }
196 cond_var_.Signal();
197 return ret;
198 }
199
[email protected]13ecb5e92013-03-07 01:35:37200 size_t GetTasksCompletedCount() {
201 base::AutoLock lock(lock_);
202 return complete_sequence_.size();
203 }
204
[email protected]098def22012-01-01 05:42:34205 void ClearCompleteSequence() {
206 base::AutoLock lock(lock_);
207 complete_sequence_.clear();
208 started_events_ = 0;
209 }
210
211 private:
[email protected]a9aaa9d12012-04-25 00:42:51212 friend class base::RefCountedThreadSafe<TestTracker>;
213 ~TestTracker() {}
214
[email protected]098def22012-01-01 05:42:34215 void SignalWorkerDone(int id) {
216 {
217 base::AutoLock lock(lock_);
218 complete_sequence_.push_back(id);
219 }
220 cond_var_.Signal();
221 }
222
223 // Protects the complete_sequence.
224 base::Lock lock_;
225
226 base::ConditionVariable cond_var_;
227
228 // Protected by lock_.
229 std::vector<int> complete_sequence_;
230
231 // Counter of the number of "block" workers that have started.
232 size_t started_events_;
233};
234
fdoray37e794792016-09-16 23:19:50235enum class SequencedWorkerPoolRedirection { NONE, TO_TASK_SCHEDULER };
236
237class SequencedWorkerPoolTest
238 : public testing::TestWithParam<SequencedWorkerPoolRedirection> {
[email protected]71b18fb2012-03-06 14:17:34239 public:
240 SequencedWorkerPoolTest()
fdoray37e794792016-09-16 23:19:50241 : pool_owner_(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")),
242 tracker_(new TestTracker) {}
243
244 void SetUp() override {
fdoraybca80902016-09-27 13:41:07245 if (RedirectedToTaskScheduler()) {
fdorayfa6f34f2017-03-29 12:25:37246 const SchedulerWorkerPoolParams worker_pool_params(
fdorayfa6f34f2017-03-29 12:25:37247 static_cast<int>(kNumWorkerThreads), TimeDelta::Max());
fdoray00b1e722017-04-28 14:16:45248 TaskScheduler::Create("SequencedWorkerPoolTest");
249 TaskScheduler::GetInstance()->Start(
250 {worker_pool_params, worker_pool_params, worker_pool_params,
251 worker_pool_params});
fdoray50a38342016-11-21 20:46:04252
253 // Unit tests run in an environment where SequencedWorkerPool is enabled
254 // without redirection to TaskScheduler. For the current unit test,
255 // disable it and re-enable it with redirection to TaskScheduler.
256 SequencedWorkerPool::DisableForProcessForTesting();
257 SequencedWorkerPool::EnableWithRedirectionToTaskSchedulerForProcess();
fdoray37e794792016-09-16 23:19:50258 }
259 }
260
261 void TearDown() override {
262 // Wait until all references to the SequencedWorkerPool are gone and destroy
263 // it. This must be done before destroying the TaskScheduler. Otherwise, the
264 // SequencedWorkerPool could try to redirect tasks to a destroyed
265 // TaskScheduler.
266 DeletePool();
267
fdoraybca80902016-09-27 13:41:07268 if (RedirectedToTaskScheduler()) {
fdoray50a38342016-11-21 20:46:04269 // Reset SequencedWorkerPool to its original state (i.e. enabled without
270 // redirection to TaskScheduler).
271 SequencedWorkerPool::DisableForProcessForTesting();
272 SequencedWorkerPool::EnableForProcess();
273
274 // Delete the registered TaskScheduler.
fdoray37e794792016-09-16 23:19:50275 DeleteTaskScheduler();
276 }
[email protected]a9aaa9d12012-04-25 00:42:51277 }
[email protected]71b18fb2012-03-06 14:17:34278
fdoraybca80902016-09-27 13:41:07279 bool RedirectedToTaskScheduler() const {
280 return GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER;
281 }
282
[email protected]71b18fb2012-03-06 14:17:34283 const scoped_refptr<SequencedWorkerPool>& pool() {
[email protected]44024782013-02-26 22:59:50284 return pool_owner_->pool();
[email protected]71b18fb2012-03-06 14:17:34285 }
[email protected]098def22012-01-01 05:42:34286 TestTracker* tracker() { return tracker_.get(); }
287
fdoray37e794792016-09-16 23:19:50288 // Waits until no tasks are running in the SequencedWorkerPool and no
289 // reference to it remain. Then, destroys the SequencedWorkerPool.
290 void DeletePool() { pool_owner_.reset(); }
291
292 // Destroys and unregisters the registered TaskScheduler, if any.
293 void DeleteTaskScheduler() {
294 if (TaskScheduler::GetInstance()) {
Jeffrey Hea9a085dd2017-08-08 15:05:01295 TaskScheduler::GetInstance()->FlushForTesting();
fdoray7bba05e2017-01-25 02:34:45296 TaskScheduler::GetInstance()->JoinForTesting();
fdoray37e794792016-09-16 23:19:50297 TaskScheduler::SetInstance(nullptr);
298 }
[email protected]44024782013-02-26 22:59:50299 }
300
[email protected]71b18fb2012-03-06 14:17:34301 void SetWillWaitForShutdownCallback(const Closure& callback) {
[email protected]44024782013-02-26 22:59:50302 pool_owner_->SetWillWaitForShutdownCallback(callback);
[email protected]71b18fb2012-03-06 14:17:34303 }
304
[email protected]098def22012-01-01 05:42:34305 // Ensures that the given number of worker threads is created by adding
306 // tasks and waiting until they complete. Worker thread creation is
307 // serialized, can happen on background threads asynchronously, and doesn't
308 // happen any more at shutdown. This means that if a test posts a bunch of
309 // tasks and calls shutdown, fewer workers will be created than the test may
310 // expect.
311 //
312 // This function ensures that this condition can't happen so tests can make
313 // assumptions about the number of workers active. See the comment in
314 // PrepareToStartAdditionalThreadIfNecessary in the .cc file for more
315 // details.
316 //
317 // It will post tasks to the queue with id -1. It also assumes this is the
318 // first thing called in a test since it will clear the complete_sequence_.
319 void EnsureAllWorkersCreated() {
320 // Create a bunch of threads, all waiting. This will cause that may
321 // workers to be created.
322 ThreadBlocker blocker;
323 for (size_t i = 0; i < kNumWorkerThreads; i++) {
sdefresne3f731c72017-05-30 12:52:52324 pool()->PostWorkerTask(
325 FROM_HERE,
326 base::BindOnce(&TestTracker::BlockTask, tracker(), -1, &blocker));
[email protected]098def22012-01-01 05:42:34327 }
328 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
329
330 // Now wake them up and wait until they're done.
331 blocker.Unblock(kNumWorkerThreads);
332 tracker()->WaitUntilTasksComplete(kNumWorkerThreads);
333
334 // Clean up the task IDs we added.
335 tracker()->ClearCompleteSequence();
336 }
337
[email protected]88bbd812012-03-14 23:17:00338 int has_work_call_count() const {
[email protected]44024782013-02-26 22:59:50339 return pool_owner_->has_work_call_count();
[email protected]88bbd812012-03-14 23:17:00340 }
341
[email protected]098def22012-01-01 05:42:34342 private:
[email protected]71b18fb2012-03-06 14:17:34343 MessageLoop message_loop_;
dcheng093de9b2016-04-04 21:25:51344 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_;
[email protected]e3f76242012-02-27 23:09:57345 const scoped_refptr<TestTracker> tracker_;
[email protected]098def22012-01-01 05:42:34346};
347
348// Checks that the given number of entries are in the tasks to complete of
349// the given tracker, and then signals the given event the given number of
erikchen8982d902015-03-31 01:06:46350// times. This is used to wake up blocked background threads before blocking
[email protected]098def22012-01-01 05:42:34351// on shutdown.
352void EnsureTasksToCompleteCountAndUnblock(scoped_refptr<TestTracker> tracker,
353 size_t expected_tasks_to_complete,
354 ThreadBlocker* blocker,
355 size_t threads_to_awake) {
356 EXPECT_EQ(
357 expected_tasks_to_complete,
358 tracker->WaitUntilTasksComplete(expected_tasks_to_complete).size());
359
360 blocker->Unblock(threads_to_awake);
361}
362
[email protected]44024782013-02-26 22:59:50363class DeletionHelper : public base::RefCountedThreadSafe<DeletionHelper> {
364 public:
365 explicit DeletionHelper(
366 const scoped_refptr<base::RefCountedData<bool> >& deleted_flag)
367 : deleted_flag_(deleted_flag) {
368 }
369
370 private:
371 friend class base::RefCountedThreadSafe<DeletionHelper>;
372 virtual ~DeletionHelper() { deleted_flag_->data = true; }
373
374 const scoped_refptr<base::RefCountedData<bool> > deleted_flag_;
375 DISALLOW_COPY_AND_ASSIGN(DeletionHelper);
376};
377
fdoray37e794792016-09-16 23:19:50378void ShouldNotRun(const scoped_refptr<DeletionHelper>& helper) {
[email protected]44024782013-02-26 22:59:50379 ADD_FAILURE() << "Should never run";
380}
381
fdoray37e794792016-09-16 23:19:50382// Tests that shutdown does not wait for delayed tasks.
383TEST_P(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) {
[email protected]44024782013-02-26 22:59:50384 // Post something to verify the pool is started up.
385 EXPECT_TRUE(pool()->PostTask(
tzik92b7a422017-04-11 15:00:44386 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 1)));
[email protected]44024782013-02-26 22:59:50387
388 scoped_refptr<base::RefCountedData<bool> > deleted_flag(
389 new base::RefCountedData<bool>(false));
390
391 base::Time posted_at(base::Time::Now());
392 // Post something that shouldn't run.
393 EXPECT_TRUE(pool()->PostDelayedTask(
394 FROM_HERE,
tzik92b7a422017-04-11 15:00:44395 base::BindOnce(&ShouldNotRun,
kylechar96f3eba2017-09-25 20:23:56396 MakeRefCounted<DeletionHelper>(deleted_flag)),
[email protected]44024782013-02-26 22:59:50397 TestTimeouts::action_timeout()));
398
399 std::vector<int> completion_sequence = tracker()->WaitUntilTasksComplete(1);
400 ASSERT_EQ(1u, completion_sequence.size());
401 ASSERT_EQ(1, completion_sequence[0]);
402
fdoray37e794792016-09-16 23:19:50403 // Shutdown the pool.
404 pool()->Shutdown();
fdoraybca80902016-09-27 13:41:07405 if (RedirectedToTaskScheduler())
fdoray37e794792016-09-16 23:19:50406 TaskScheduler::GetInstance()->Shutdown();
[email protected]44024782013-02-26 22:59:50407
408 // Verify that we didn't block until the task was due.
409 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout());
410
fdoraydc7bca92016-09-22 14:55:44411 // TaskScheduler shouldn't delete the delayed task before it is itself
412 // deleted. SequencedWorkerPool starts deleting tasks as soon as its
413 // Shutdown() method is called (see SequencedWorkerPool::Inner::GetWork).
fdoraybca80902016-09-27 13:41:07414 if (RedirectedToTaskScheduler())
fdoraydc7bca92016-09-22 14:55:44415 EXPECT_FALSE(deleted_flag->data);
416
417 // Verify that the delayed task is deleted once the SequencedWorkerPool (and
418 // the TaskScheduler when applicable) have been deleted.
fdoray37e794792016-09-16 23:19:50419 DeletePool();
fdoraybca80902016-09-27 13:41:07420 if (RedirectedToTaskScheduler())
fdoray37e794792016-09-16 23:19:50421 DeleteTaskScheduler();
422 EXPECT_TRUE(deleted_flag->data);
[email protected]44024782013-02-26 22:59:50423}
424
[email protected]098def22012-01-01 05:42:34425// Tests that same-named tokens have the same ID.
fdoray37e794792016-09-16 23:19:50426TEST_P(SequencedWorkerPoolTest, NamedTokens) {
[email protected]098def22012-01-01 05:42:34427 const std::string name1("hello");
428 SequencedWorkerPool::SequenceToken token1 =
[email protected]e3f76242012-02-27 23:09:57429 pool()->GetNamedSequenceToken(name1);
[email protected]098def22012-01-01 05:42:34430
[email protected]e3f76242012-02-27 23:09:57431 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken();
[email protected]098def22012-01-01 05:42:34432
433 const std::string name3("goodbye");
434 SequencedWorkerPool::SequenceToken token3 =
[email protected]e3f76242012-02-27 23:09:57435 pool()->GetNamedSequenceToken(name3);
[email protected]098def22012-01-01 05:42:34436
437 // All 3 tokens should be different.
438 EXPECT_FALSE(token1.Equals(token2));
439 EXPECT_FALSE(token1.Equals(token3));
440 EXPECT_FALSE(token2.Equals(token3));
441
442 // Requesting the same name again should give the same value.
443 SequencedWorkerPool::SequenceToken token1again =
[email protected]e3f76242012-02-27 23:09:57444 pool()->GetNamedSequenceToken(name1);
[email protected]098def22012-01-01 05:42:34445 EXPECT_TRUE(token1.Equals(token1again));
446
447 SequencedWorkerPool::SequenceToken token3again =
[email protected]e3f76242012-02-27 23:09:57448 pool()->GetNamedSequenceToken(name3);
[email protected]098def22012-01-01 05:42:34449 EXPECT_TRUE(token3.Equals(token3again));
450}
451
452// Tests that posting a bunch of tasks (many more than the number of worker
453// threads) runs them all.
fdoray37e794792016-09-16 23:19:50454TEST_P(SequencedWorkerPoolTest, LotsOfTasks) {
sdefresne3f731c72017-05-30 12:52:52455 pool()->PostWorkerTask(FROM_HERE,
456 base::BindOnce(&TestTracker::SlowTask, tracker(), 0));
[email protected]098def22012-01-01 05:42:34457
458 const size_t kNumTasks = 20;
459 for (size_t i = 1; i < kNumTasks; i++) {
sdefresne3f731c72017-05-30 12:52:52460 pool()->PostWorkerTask(
461 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), i));
[email protected]098def22012-01-01 05:42:34462 }
463
464 std::vector<int> result = tracker()->WaitUntilTasksComplete(kNumTasks);
465 EXPECT_EQ(kNumTasks, result.size());
466}
467
[email protected]18481252012-02-29 21:05:16468// Tests that posting a bunch of tasks (many more than the number of
469// worker threads) to two pools simultaneously runs them all twice.
470// This test is meant to shake out any concurrency issues between
471// pools (like histograms).
fdoray37e794792016-09-16 23:19:50472TEST_P(SequencedWorkerPoolTest, LotsOfTasksTwoPools) {
[email protected]71b18fb2012-03-06 14:17:34473 SequencedWorkerPoolOwner pool1(kNumWorkerThreads, "test1");
474 SequencedWorkerPoolOwner pool2(kNumWorkerThreads, "test2");
[email protected]18481252012-02-29 21:05:16475
476 base::Closure slow_task = base::Bind(&TestTracker::SlowTask, tracker(), 0);
sdefresne3f731c72017-05-30 12:52:52477 pool1.pool()->PostWorkerTask(FROM_HERE, slow_task);
478 pool2.pool()->PostWorkerTask(FROM_HERE, slow_task);
[email protected]18481252012-02-29 21:05:16479
480 const size_t kNumTasks = 20;
481 for (size_t i = 1; i < kNumTasks; i++) {
482 base::Closure fast_task =
483 base::Bind(&TestTracker::FastTask, tracker(), i);
sdefresne3f731c72017-05-30 12:52:52484 pool1.pool()->PostWorkerTask(FROM_HERE, fast_task);
485 pool2.pool()->PostWorkerTask(FROM_HERE, fast_task);
[email protected]18481252012-02-29 21:05:16486 }
487
488 std::vector<int> result =
489 tracker()->WaitUntilTasksComplete(2*kNumTasks);
[email protected]bdb2e102012-07-21 04:58:04490 EXPECT_EQ(2 * kNumTasks, result.size());
[email protected]18481252012-02-29 21:05:16491}
492
[email protected]098def22012-01-01 05:42:34493// Test that tasks with the same sequence token are executed in order but don't
494// affect other tasks.
fdoray37e794792016-09-16 23:19:50495TEST_P(SequencedWorkerPoolTest, Sequence) {
[email protected]098def22012-01-01 05:42:34496 // Fill all the worker threads except one.
497 const size_t kNumBackgroundTasks = kNumWorkerThreads - 1;
498 ThreadBlocker background_blocker;
499 for (size_t i = 0; i < kNumBackgroundTasks; i++) {
sdefresne3f731c72017-05-30 12:52:52500 pool()->PostWorkerTask(FROM_HERE,
501 base::BindOnce(&TestTracker::BlockTask, tracker(), i,
502 &background_blocker));
[email protected]098def22012-01-01 05:42:34503 }
504 tracker()->WaitUntilTasksBlocked(kNumBackgroundTasks);
505
506 // Create two tasks with the same sequence token, one that will block on the
507 // event, and one which will just complete quickly when it's run. Since there
508 // is one worker thread free, the first task will start and then block, and
509 // the second task should be waiting.
510 ThreadBlocker blocker;
[email protected]e3f76242012-02-27 23:09:57511 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken();
512 pool()->PostSequencedWorkerTask(
[email protected]098def22012-01-01 05:42:34513 token1, FROM_HERE,
tzik92b7a422017-04-11 15:00:44514 base::BindOnce(&TestTracker::BlockTask, tracker(), 100, &blocker));
[email protected]e3f76242012-02-27 23:09:57515 pool()->PostSequencedWorkerTask(
[email protected]098def22012-01-01 05:42:34516 token1, FROM_HERE,
tzik92b7a422017-04-11 15:00:44517 base::BindOnce(&TestTracker::FastTask, tracker(), 101));
[email protected]098def22012-01-01 05:42:34518 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size());
519
520 // Create another two tasks as above with a different token. These will be
521 // blocked since there are no slots to run.
[email protected]e3f76242012-02-27 23:09:57522 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken();
523 pool()->PostSequencedWorkerTask(
[email protected]098def22012-01-01 05:42:34524 token2, FROM_HERE,
tzik92b7a422017-04-11 15:00:44525 base::BindOnce(&TestTracker::FastTask, tracker(), 200));
[email protected]e3f76242012-02-27 23:09:57526 pool()->PostSequencedWorkerTask(
[email protected]098def22012-01-01 05:42:34527 token2, FROM_HERE,
tzik92b7a422017-04-11 15:00:44528 base::BindOnce(&TestTracker::FastTask, tracker(), 201));
[email protected]098def22012-01-01 05:42:34529 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size());
530
531 // Let one background task complete. This should then let both tasks of
532 // token2 run to completion in order. The second task of token1 should still
533 // be blocked.
534 background_blocker.Unblock(1);
535 std::vector<int> result = tracker()->WaitUntilTasksComplete(3);
536 ASSERT_EQ(3u, result.size());
537 EXPECT_EQ(200, result[1]);
538 EXPECT_EQ(201, result[2]);
539
540 // Finish the rest of the background tasks. This should leave some workers
541 // free with the second token1 task still blocked on the first.
542 background_blocker.Unblock(kNumBackgroundTasks - 1);
543 EXPECT_EQ(kNumBackgroundTasks + 2,
544 tracker()->WaitUntilTasksComplete(kNumBackgroundTasks + 2).size());
545
546 // Allow the first task of token1 to complete. This should run the second.
547 blocker.Unblock(1);
548 result = tracker()->WaitUntilTasksComplete(kNumBackgroundTasks + 4);
549 ASSERT_EQ(kNumBackgroundTasks + 4, result.size());
550 EXPECT_EQ(100, result[result.size() - 2]);
551 EXPECT_EQ(101, result[result.size() - 1]);
552}
553
[email protected]bdb2e102012-07-21 04:58:04554// Tests that any tasks posted after Shutdown are ignored.
[email protected]c01c2642013-01-15 18:49:32555// Disabled for flakiness. See http://crbug.com/166451.
fdoray37e794792016-09-16 23:19:50556TEST_P(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) {
[email protected]bdb2e102012-07-21 04:58:04557 // Start tasks to take all the threads and block them.
558 EnsureAllWorkersCreated();
559 ThreadBlocker blocker;
560 for (size_t i = 0; i < kNumWorkerThreads; i++) {
sdefresne3f731c72017-05-30 12:52:52561 pool()->PostWorkerTask(FROM_HERE, base::BindOnce(&TestTracker::BlockTask,
562 tracker(), i, &blocker));
[email protected]bdb2e102012-07-21 04:58:04563 }
564 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
565
[email protected]bdb2e102012-07-21 04:58:04566 SetWillWaitForShutdownCallback(
567 base::Bind(&EnsureTasksToCompleteCountAndUnblock,
568 scoped_refptr<TestTracker>(tracker()), 0,
569 &blocker, kNumWorkerThreads));
[email protected]270f2cf2012-12-19 01:56:37570
571 // Shutdown the worker pool. This should discard all non-blocking tasks.
572 const int kMaxNewBlockingTasksAfterShutdown = 100;
573 pool()->Shutdown(kMaxNewBlockingTasksAfterShutdown);
[email protected]bdb2e102012-07-21 04:58:04574
575 int old_has_work_call_count = has_work_call_count();
576
577 std::vector<int> result =
578 tracker()->WaitUntilTasksComplete(kNumWorkerThreads);
579
[email protected]270f2cf2012-12-19 01:56:37580 // The kNumWorkerThread items should have completed, in no particular order.
[email protected]bdb2e102012-07-21 04:58:04581 ASSERT_EQ(kNumWorkerThreads, result.size());
thestig6c335d42015-12-07 18:25:34582 for (size_t i = 0; i < kNumWorkerThreads; i++)
583 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i)));
[email protected]bdb2e102012-07-21 04:58:04584
585 // No further tasks, regardless of shutdown mode, should be allowed.
586 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior(
tzik92b7a422017-04-11 15:00:44587 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 100),
[email protected]bdb2e102012-07-21 04:58:04588 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
589 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior(
tzik92b7a422017-04-11 15:00:44590 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 101),
[email protected]bdb2e102012-07-21 04:58:04591 SequencedWorkerPool::SKIP_ON_SHUTDOWN));
592 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior(
tzik92b7a422017-04-11 15:00:44593 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 102),
[email protected]bdb2e102012-07-21 04:58:04594 SequencedWorkerPool::BLOCK_SHUTDOWN));
595
596 ASSERT_EQ(old_has_work_call_count, has_work_call_count());
597}
598
fdoray37e794792016-09-16 23:19:50599TEST_P(SequencedWorkerPoolTest, AllowsAfterShutdown) {
[email protected]270f2cf2012-12-19 01:56:37600 // Test that <n> new blocking tasks are allowed provided they're posted
601 // by a running tasks.
602 EnsureAllWorkersCreated();
603 ThreadBlocker blocker;
604
605 // Start tasks to take all the threads and block them.
606 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads);
607 for (int i = 0; i < kNumBlockTasks; ++i) {
sdefresne3f731c72017-05-30 12:52:52608 EXPECT_TRUE(pool()->PostWorkerTask(
[email protected]270f2cf2012-12-19 01:56:37609 FROM_HERE,
tzik92b7a422017-04-11 15:00:44610 base::BindOnce(&TestTracker::BlockTask, tracker(), i, &blocker)));
[email protected]270f2cf2012-12-19 01:56:37611 }
612 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
613
614 // Queue up shutdown blocking tasks behind those which will attempt to post
fdoray3871591052016-10-04 13:53:39615 // additional tasks when run, PostAdditionalTasks attempts to post 3
[email protected]270f2cf2012-12-19 01:56:37616 // new FastTasks, one for each shutdown_behavior.
617 const int kNumQueuedTasks = static_cast<int>(kNumWorkerThreads);
618 for (int i = 0; i < kNumQueuedTasks; ++i) {
619 EXPECT_TRUE(pool()->PostWorkerTaskWithShutdownBehavior(
tzik92b7a422017-04-11 15:00:44620 FROM_HERE,
621 base::BindOnce(&TestTracker::PostAdditionalTasks, tracker(), i,
622 base::RetainedRef(pool()), false),
[email protected]270f2cf2012-12-19 01:56:37623 SequencedWorkerPool::BLOCK_SHUTDOWN));
624 }
625
fdoray3871591052016-10-04 13:53:39626 // Half the additional blocking tasks will be allowed to run.
627 constexpr int kNumNewBlockingTasksToAllow = kNumWorkerThreads / 2;
[email protected]270f2cf2012-12-19 01:56:37628
fdoray3871591052016-10-04 13:53:39629 if (RedirectedToTaskScheduler()) {
630 // When redirection to TaskScheduler is enabled,
631 // SequencedWorkerPool::Shutdown() sets the number of additional
632 // BLOCK_SHUTDOWN tasks that can be posted and returns without waiting for
633 // pending BLOCK_SHUTDOWN tasks to complete their execution.
634 pool()->Shutdown(kNumNewBlockingTasksToAllow);
635
636 // Unblock tasks.
637 EnsureTasksToCompleteCountAndUnblock(tracker(), 0, &blocker,
638 kNumBlockTasks);
639
640 // TaskScheduler::Shutdown() waits for pending BLOCK_SHUTDOWN tasks to
641 // complete their execution.
642 TaskScheduler::GetInstance()->Shutdown();
643 } else {
644 // Once shutdown starts, unblock tasks.
645 SetWillWaitForShutdownCallback(base::Bind(
646 &EnsureTasksToCompleteCountAndUnblock,
647 scoped_refptr<TestTracker>(tracker()), 0, &blocker, kNumBlockTasks));
648
649 // Set the number of additional BLOCK_SHUTDOWN tasks that can be posted and
650 // wait for pending BLOCK_SHUTDOWN tasks to complete their execution.
651 pool()->Shutdown(kNumNewBlockingTasksToAllow);
652 }
[email protected]270f2cf2012-12-19 01:56:37653
654 // Ensure that the correct number of tasks actually got run.
655 tracker()->WaitUntilTasksComplete(static_cast<size_t>(
656 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow));
657
658 // Clean up the task IDs we added and go home.
659 tracker()->ClearCompleteSequence();
660}
661
erikchen8982d902015-03-31 01:06:46662// Tests that blocking tasks can still be posted during shutdown, as long as
663// the task is not being posted within the context of a running task.
fdoray37e794792016-09-16 23:19:50664TEST_P(SequencedWorkerPoolTest,
erikchen8982d902015-03-31 01:06:46665 AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) {
666 EnsureAllWorkersCreated();
667 ThreadBlocker blocker;
668
669 // Start tasks to take all the threads and block them.
670 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads);
671 for (int i = 0; i < kNumBlockTasks; ++i) {
sdefresne3f731c72017-05-30 12:52:52672 EXPECT_TRUE(pool()->PostWorkerTask(
erikchen8982d902015-03-31 01:06:46673 FROM_HERE,
tzik92b7a422017-04-11 15:00:44674 base::BindOnce(&TestTracker::BlockTask, tracker(), i, &blocker)));
erikchen8982d902015-03-31 01:06:46675 }
676 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
677
fdoray3871591052016-10-04 13:53:39678 constexpr int kNumNewBlockingTasksToAllow = 1;
679
680 if (RedirectedToTaskScheduler()) {
681 // When redirection to TaskScheduler is enabled,
682 // SequencedWorkerPool::Shutdown() sets the number of additional
683 // BLOCK_SHUTDOWN tasks that can be posted and returns without waiting for
684 // pending BLOCK_SHUTDOWN tasks to complete their execution.
685 pool()->Shutdown(kNumNewBlockingTasksToAllow);
686
687 // Post a blocking task and unblock tasks.
688 tracker()->PostBlockingTaskThenUnblockThreads(pool(), &blocker,
689 kNumWorkerThreads);
690
691 // TaskScheduler::Shutdown() waits for pending BLOCK_SHUTDOWN tasks to
692 // complete their execution.
693 TaskScheduler::GetInstance()->Shutdown();
694 } else {
695 // Once shutdown starts, post a blocking task and unblock tasks.
696 SetWillWaitForShutdownCallback(
697 base::Bind(&TestTracker::PostBlockingTaskThenUnblockThreads,
698 scoped_refptr<TestTracker>(tracker()), pool(), &blocker,
699 kNumWorkerThreads));
700
701 // Set the number of additional BLOCK_SHUTDOWN tasks that can be posted and
702 // wait for pending BLOCK_SHUTDOWN tasks to complete their execution.
703 pool()->Shutdown(kNumNewBlockingTasksToAllow);
704 }
erikchen8982d902015-03-31 01:06:46705
706 // Ensure that the correct number of tasks actually got run.
fdoray3871591052016-10-04 13:53:39707 tracker()->WaitUntilTasksComplete(
708 static_cast<size_t>(kNumWorkerThreads + kNumNewBlockingTasksToAllow));
erikchen8982d902015-03-31 01:06:46709 tracker()->ClearCompleteSequence();
710}
711
[email protected]098def22012-01-01 05:42:34712// Tests that unrun tasks are discarded properly according to their shutdown
713// mode.
fdoray37e794792016-09-16 23:19:50714TEST_P(SequencedWorkerPoolTest, DiscardOnShutdown) {
715 // As tested by
716 // TaskSchedulerTaskTrackerTest.WillPostBeforeShutdownRunDuringShutdown, on
717 // shutdown, the TaskScheduler discards SKIP_ON_SHUTDOWN and
718 // CONTINUE_ON_SHUTDOWN tasks and runs BLOCK_SHUTDOWN tasks. However, since it
719 // doesn't provide a way to run a callback from inside its Shutdown() method,
720 // it would be hard to make this test work with redirection enabled.
fdoraybca80902016-09-27 13:41:07721 if (RedirectedToTaskScheduler())
fdoray37e794792016-09-16 23:19:50722 return;
723
[email protected]098def22012-01-01 05:42:34724 // Start tasks to take all the threads and block them.
725 EnsureAllWorkersCreated();
726 ThreadBlocker blocker;
727 for (size_t i = 0; i < kNumWorkerThreads; i++) {
sdefresne3f731c72017-05-30 12:52:52728 pool()->PostWorkerTask(FROM_HERE, base::BindOnce(&TestTracker::BlockTask,
729 tracker(), i, &blocker));
[email protected]098def22012-01-01 05:42:34730 }
731 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
732
733 // Create some tasks with different shutdown modes.
[email protected]e3f76242012-02-27 23:09:57734 pool()->PostWorkerTaskWithShutdownBehavior(
tzik92b7a422017-04-11 15:00:44735 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 100),
[email protected]098def22012-01-01 05:42:34736 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
[email protected]e3f76242012-02-27 23:09:57737 pool()->PostWorkerTaskWithShutdownBehavior(
tzik92b7a422017-04-11 15:00:44738 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 101),
[email protected]098def22012-01-01 05:42:34739 SequencedWorkerPool::SKIP_ON_SHUTDOWN);
[email protected]e3f76242012-02-27 23:09:57740 pool()->PostWorkerTaskWithShutdownBehavior(
tzik92b7a422017-04-11 15:00:44741 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 102),
[email protected]098def22012-01-01 05:42:34742 SequencedWorkerPool::BLOCK_SHUTDOWN);
743
744 // Shutdown the worker pool. This should discard all non-blocking tasks.
[email protected]71b18fb2012-03-06 14:17:34745 SetWillWaitForShutdownCallback(
[email protected]098def22012-01-01 05:42:34746 base::Bind(&EnsureTasksToCompleteCountAndUnblock,
747 scoped_refptr<TestTracker>(tracker()), 0,
[email protected]71b18fb2012-03-06 14:17:34748 &blocker, kNumWorkerThreads));
[email protected]e3f76242012-02-27 23:09:57749 pool()->Shutdown();
[email protected]098def22012-01-01 05:42:34750
[email protected]bdb2e102012-07-21 04:58:04751 std::vector<int> result =
752 tracker()->WaitUntilTasksComplete(kNumWorkerThreads + 1);
[email protected]098def22012-01-01 05:42:34753
754 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN
755 // one, in no particular order.
[email protected]bdb2e102012-07-21 04:58:04756 ASSERT_EQ(kNumWorkerThreads + 1, result.size());
thestig6c335d42015-12-07 18:25:34757 for (size_t i = 0; i < kNumWorkerThreads; i++)
758 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i)));
759 EXPECT_TRUE(ContainsValue(result, 102));
[email protected]098def22012-01-01 05:42:34760}
761
762// Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown.
fdoray37e794792016-09-16 23:19:50763TEST_P(SequencedWorkerPoolTest, ContinueOnShutdown) {
[email protected]497ec462012-04-11 22:42:29764 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior(
765 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
766 scoped_refptr<SequencedTaskRunner> sequenced_runner(
767 pool()->GetSequencedTaskRunnerWithShutdownBehavior(
768 pool()->GetSequenceToken(),
769 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
[email protected]098def22012-01-01 05:42:34770 EnsureAllWorkersCreated();
771 ThreadBlocker blocker;
[email protected]e3f76242012-02-27 23:09:57772 pool()->PostWorkerTaskWithShutdownBehavior(
[email protected]098def22012-01-01 05:42:34773 FROM_HERE,
tzik92b7a422017-04-11 15:00:44774 base::BindOnce(&TestTracker::BlockTask, tracker(), 0, &blocker),
[email protected]098def22012-01-01 05:42:34775 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
tzik92b7a422017-04-11 15:00:44776 runner->PostTask(FROM_HERE, base::BindOnce(&TestTracker::BlockTask, tracker(),
777 1, &blocker));
778 sequenced_runner->PostTask(FROM_HERE, base::BindOnce(&TestTracker::BlockTask,
779 tracker(), 2, &blocker));
[email protected]497ec462012-04-11 22:42:29780
781 tracker()->WaitUntilTasksBlocked(3);
[email protected]098def22012-01-01 05:42:34782
783 // This should not block. If this test hangs, it means it failed.
[email protected]e3f76242012-02-27 23:09:57784 pool()->Shutdown();
fdoraybca80902016-09-27 13:41:07785 if (RedirectedToTaskScheduler())
fdoray37e794792016-09-16 23:19:50786 TaskScheduler::GetInstance()->Shutdown();
[email protected]098def22012-01-01 05:42:34787
788 // The task should not have completed yet.
789 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size());
790
791 // Posting more tasks should fail.
[email protected]e3f76242012-02-27 23:09:57792 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior(
tzik92b7a422017-04-11 15:00:44793 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 0),
[email protected]098def22012-01-01 05:42:34794 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
[email protected]497ec462012-04-11 22:42:29795 EXPECT_FALSE(runner->PostTask(
tzik92b7a422017-04-11 15:00:44796 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 0)));
[email protected]497ec462012-04-11 22:42:29797 EXPECT_FALSE(sequenced_runner->PostTask(
tzik92b7a422017-04-11 15:00:44798 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 0)));
[email protected]098def22012-01-01 05:42:34799
[email protected]497ec462012-04-11 22:42:29800 // Continue the background thread and make sure the tasks can complete.
801 blocker.Unblock(3);
802 std::vector<int> result = tracker()->WaitUntilTasksComplete(3);
803 EXPECT_EQ(3u, result.size());
[email protected]098def22012-01-01 05:42:34804}
805
[email protected]bdb2e102012-07-21 04:58:04806// Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown
807// until they stop, but tasks not yet started do not.
fdoray37e794792016-09-16 23:19:50808TEST_P(SequencedWorkerPoolTest, SkipOnShutdown) {
809 // As tested by
810 // TaskSchedulerTaskTrackerTest.WillPostAndRunLongTaskBeforeShutdown and
811 // TaskSchedulerTaskTrackerTest.WillPostBeforeShutdownRunDuringShutdown, the
812 // TaskScheduler correctly handles SKIP_ON_SHUTDOWN tasks. However, since it
813 // doesn't provide a way to run a callback from inside its Shutdown() method,
814 // it would be hard to make this test work with redirection enabled.
fdoraybca80902016-09-27 13:41:07815 if (RedirectedToTaskScheduler())
fdoray37e794792016-09-16 23:19:50816 return;
817
[email protected]bdb2e102012-07-21 04:58:04818 // Start tasks to take all the threads and block them.
819 EnsureAllWorkersCreated();
820 ThreadBlocker blocker;
821
822 // Now block all the threads with SKIP_ON_SHUTDOWN. Shutdown() should not
823 // return until these tasks have completed.
824 for (size_t i = 0; i < kNumWorkerThreads; i++) {
825 pool()->PostWorkerTaskWithShutdownBehavior(
826 FROM_HERE,
tzik92b7a422017-04-11 15:00:44827 base::BindOnce(&TestTracker::BlockTask, tracker(), i, &blocker),
[email protected]bdb2e102012-07-21 04:58:04828 SequencedWorkerPool::SKIP_ON_SHUTDOWN);
829 }
830 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
831
832 // Now post an additional task as SKIP_ON_SHUTDOWN, which should not be
833 // executed once Shutdown() has been called.
834 pool()->PostWorkerTaskWithShutdownBehavior(
835 FROM_HERE,
tzik92b7a422017-04-11 15:00:44836 base::BindOnce(&TestTracker::BlockTask, tracker(), 0, &blocker),
[email protected]bdb2e102012-07-21 04:58:04837 SequencedWorkerPool::SKIP_ON_SHUTDOWN);
838
839 // This callback will only be invoked if SKIP_ON_SHUTDOWN tasks that have
840 // been started block shutdown.
841 SetWillWaitForShutdownCallback(
842 base::Bind(&EnsureTasksToCompleteCountAndUnblock,
843 scoped_refptr<TestTracker>(tracker()), 0,
844 &blocker, kNumWorkerThreads));
845
846 // No tasks should have completed yet.
847 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size());
848
849 // This should not block. If this test hangs, it means it failed.
850 pool()->Shutdown();
851
852 // Shutdown should not return until all of the tasks have completed.
853 std::vector<int> result =
854 tracker()->WaitUntilTasksComplete(kNumWorkerThreads);
855
856 // Only tasks marked SKIP_ON_SHUTDOWN that were already started should be
857 // allowed to complete. No additional non-blocking tasks should have been
858 // started.
859 ASSERT_EQ(kNumWorkerThreads, result.size());
thestig6c335d42015-12-07 18:25:34860 for (size_t i = 0; i < kNumWorkerThreads; i++)
861 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i)));
[email protected]bdb2e102012-07-21 04:58:04862}
863
[email protected]857b6002012-03-12 21:42:13864// Ensure all worker threads are created, and then trigger a spurious
865// work signal. This shouldn't cause any other work signals to be
866// triggered. This is a regression test for http://crbug.com/117469.
fdoray37e794792016-09-16 23:19:50867TEST_P(SequencedWorkerPoolTest, SpuriousWorkSignal) {
868 // This test doesn't apply when tasks are redirected to the TaskScheduler.
fdoraybca80902016-09-27 13:41:07869 if (RedirectedToTaskScheduler())
fdoray37e794792016-09-16 23:19:50870 return;
871
[email protected]857b6002012-03-12 21:42:13872 EnsureAllWorkersCreated();
[email protected]88bbd812012-03-14 23:17:00873 int old_has_work_call_count = has_work_call_count();
874 pool()->SignalHasWorkForTesting();
[email protected]857b6002012-03-12 21:42:13875 // This is inherently racy, but can only produce false positives.
876 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
[email protected]88bbd812012-03-14 23:17:00877 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count());
[email protected]857b6002012-03-12 21:42:13878}
879
fdoray2c56f2d2016-09-15 21:31:19880void VerifyRunsTasksOnCurrentThread(
fdoraybca80902016-09-27 13:41:07881 bool redirected_to_task_scheduler,
fdoray2c56f2d2016-09-15 21:31:19882 scoped_refptr<TaskRunner> test_positive_task_runner,
883 scoped_refptr<TaskRunner> test_negative_task_runner,
[email protected]f6f074d02012-03-30 22:33:46884 SequencedWorkerPool* pool,
885 SequencedWorkerPool* unused_pool) {
Yeola89b2662017-07-25 17:09:10886 EXPECT_TRUE(test_positive_task_runner->RunsTasksInCurrentSequence());
887 EXPECT_FALSE(test_negative_task_runner->RunsTasksInCurrentSequence());
888 EXPECT_TRUE(pool->RunsTasksInCurrentSequence());
fdoray37e794792016-09-16 23:19:50889
890 // Tasks posted to different SequencedWorkerPools may run on the same
891 // TaskScheduler threads.
fdoraybca80902016-09-27 13:41:07892 if (redirected_to_task_scheduler)
Yeola89b2662017-07-25 17:09:10893 EXPECT_TRUE(unused_pool->RunsTasksInCurrentSequence());
fdoray37e794792016-09-16 23:19:50894 else
Yeola89b2662017-07-25 17:09:10895 EXPECT_FALSE(unused_pool->RunsTasksInCurrentSequence());
[email protected]f6f074d02012-03-30 22:33:46896}
897
fdoray2c56f2d2016-09-15 21:31:19898// Verify correctness of the RunsTasksOnCurrentThread() method on
899// SequencedWorkerPool and on TaskRunners it returns.
fdoray37e794792016-09-16 23:19:50900TEST_P(SequencedWorkerPoolTest, RunsTasksOnCurrentThread) {
fdoray2c56f2d2016-09-15 21:31:19901 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_1 =
902 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken());
903 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_2 =
904 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken());
905 const scoped_refptr<TaskRunner> unsequenced_task_runner =
906 pool()->GetTaskRunnerWithShutdownBehavior(
907 SequencedWorkerPool::BLOCK_SHUTDOWN);
[email protected]f6f074d02012-03-30 22:33:46908
tapted012326b2015-12-03 04:43:05909 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool");
[email protected]f6f074d02012-03-30 22:33:46910
Yeola89b2662017-07-25 17:09:10911 EXPECT_FALSE(pool()->RunsTasksInCurrentSequence());
912 EXPECT_FALSE(sequenced_task_runner_1->RunsTasksInCurrentSequence());
913 EXPECT_FALSE(sequenced_task_runner_2->RunsTasksInCurrentSequence());
914 EXPECT_FALSE(unsequenced_task_runner->RunsTasksInCurrentSequence());
915 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksInCurrentSequence());
[email protected]f6f074d02012-03-30 22:33:46916
fdoray2c56f2d2016-09-15 21:31:19917 // From a task posted to |sequenced_task_runner_1|:
918 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns true.
919 // - sequenced_task_runner_2->RunsTasksOnCurrentThread() returns false.
920 // - pool()->RunsTasksOnCurrentThread() returns true.
921 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false.
922 sequenced_task_runner_1->PostTask(
fdoraybca80902016-09-27 13:41:07923 FROM_HERE,
tzik92b7a422017-04-11 15:00:44924 base::BindOnce(&VerifyRunsTasksOnCurrentThread,
925 RedirectedToTaskScheduler(), sequenced_task_runner_1,
926 sequenced_task_runner_2, base::RetainedRef(pool()),
927 base::RetainedRef(unused_pool_owner.pool())));
fdoray2c56f2d2016-09-15 21:31:19928 // From a task posted to |unsequenced_task_runner|:
929 // - unsequenced_task_runner->RunsTasksOnCurrentThread() returns true.
930 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns false.
931 // - pool()->RunsTasksOnCurrentThread() returns true.
932 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false.
933 unsequenced_task_runner->PostTask(
fdoraybca80902016-09-27 13:41:07934 FROM_HERE,
tzik92b7a422017-04-11 15:00:44935 base::BindOnce(&VerifyRunsTasksOnCurrentThread,
936 RedirectedToTaskScheduler(), unsequenced_task_runner,
937 sequenced_task_runner_1, base::RetainedRef(pool()),
938 base::RetainedRef(unused_pool_owner.pool())));
[email protected]f6f074d02012-03-30 22:33:46939}
940
erikcheneae82f22015-02-26 19:37:42941// Checks that tasks are destroyed in the right context during shutdown. If a
942// task is destroyed while SequencedWorkerPool's global lock is held,
943// SequencedWorkerPool might deadlock.
fdoray37e794792016-09-16 23:19:50944TEST_P(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) {
945 // Note: TaskScheduler destroys tasks when it is deleted rather than on
946 // shutdown. In production, it should never be destroyed.
947
erikcheneae82f22015-02-26 19:37:42948 for (int i = 0; i < 4; ++i) {
949 scoped_refptr<DestructionDeadlockChecker> checker(
950 new DestructionDeadlockChecker(pool()));
951 tracker()->PostRepostingTask(pool(), checker);
952 }
953
954 // Shutting down the pool should destroy the DestructionDeadlockCheckers,
955 // which in turn should not deadlock in their destructors.
956 pool()->Shutdown();
957}
958
erikchen19249bcc2015-03-13 22:57:37959// Similar to the test AvoidsDeadlockOnShutdown, but there are now also
960// sequenced, blocking tasks in the queue during shutdown.
fdoray37e794792016-09-16 23:19:50961TEST_P(SequencedWorkerPoolTest,
erikchen19249bcc2015-03-13 22:57:37962 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) {
fdoray37e794792016-09-16 23:19:50963 // This test continuously posts BLOCK_SHUTDOWN tasks
964 // (PostRepostingBlockingTask). It can't run when tasks are redirected to
965 // TaskScheduler because TaskScheduler doesn't provide a way to limit the
966 // number of BLOCK_SHUTDOWN tasks posted during shutdown.
fdoraybca80902016-09-27 13:41:07967 if (RedirectedToTaskScheduler())
fdoray37e794792016-09-16 23:19:50968 return;
969
erikchen19249bcc2015-03-13 22:57:37970 const std::string sequence_token_name("name");
971 for (int i = 0; i < 4; ++i) {
972 scoped_refptr<DestructionDeadlockChecker> checker(
973 new DestructionDeadlockChecker(pool()));
974 tracker()->PostRepostingTask(pool(), checker);
975
976 SequencedWorkerPool::SequenceToken token1 =
977 pool()->GetNamedSequenceToken(sequence_token_name);
978 tracker()->PostRepostingBlockingTask(pool(), token1);
979 }
980
981 // Shutting down the pool should destroy the DestructionDeadlockCheckers,
982 // which in turn should not deadlock in their destructors.
983 pool()->Shutdown();
984}
985
[email protected]13ecb5e92013-03-07 01:35:37986// Verify that FlushForTesting works as intended.
fdoray37e794792016-09-16 23:19:50987TEST_P(SequencedWorkerPoolTest, FlushForTesting) {
[email protected]13ecb5e92013-03-07 01:35:37988 // Should be fine to call on a new instance.
989 pool()->FlushForTesting();
990
991 // Queue up a bunch of work, including a long delayed task and
992 // a task that produces additional tasks as an artifact.
fdoray940082f2017-05-16 19:47:21993 pool()->PostDelayedTask(FROM_HERE,
994 base::BindOnce(&TestTracker::FastTask, tracker(), 0),
995 TimeDelta::FromMinutes(5));
sdefresne3f731c72017-05-30 12:52:52996 pool()->PostWorkerTask(FROM_HERE,
997 base::BindOnce(&TestTracker::SlowTask, tracker(), 0));
[email protected]13ecb5e92013-03-07 01:35:37998 const size_t kNumFastTasks = 20;
999 for (size_t i = 0; i < kNumFastTasks; i++) {
sdefresne3f731c72017-05-30 12:52:521000 pool()->PostWorkerTask(
1001 FROM_HERE, base::BindOnce(&TestTracker::FastTask, tracker(), 0));
[email protected]13ecb5e92013-03-07 01:35:371002 }
sdefresne3f731c72017-05-30 12:52:521003 pool()->PostWorkerTask(
tzik92b7a422017-04-11 15:00:441004 FROM_HERE, base::BindOnce(&TestTracker::PostAdditionalTasks, tracker(), 0,
1005 base::RetainedRef(pool()), true));
[email protected]13ecb5e92013-03-07 01:35:371006
1007 // We expect all except the delayed task to have been run. We verify all
[email protected]4f60d802013-04-18 05:41:231008 // closures have been deleted by looking at the refcount of the
[email protected]13ecb5e92013-03-07 01:35:371009 // tracker.
1010 EXPECT_FALSE(tracker()->HasOneRef());
1011 pool()->FlushForTesting();
[email protected]13ecb5e92013-03-07 01:35:371012 EXPECT_EQ(1 + kNumFastTasks + 1 + 3, tracker()->GetTasksCompletedCount());
fdoraybca80902016-09-27 13:41:071013 // TaskScheduler deletes unexecuted delayed tasks as part of ~TaskScheduler()
1014 // instead of TaskScheduler::FlushForTesting().
1015 EXPECT_EQ(!RedirectedToTaskScheduler(), tracker()->HasOneRef());
[email protected]13ecb5e92013-03-07 01:35:371016
1017 // Should be fine to call on an idle instance with all threads created, and
1018 // spamming the method shouldn't deadlock or confuse the class.
1019 pool()->FlushForTesting();
1020 pool()->FlushForTesting();
1021
1022 // Should be fine to call after shutdown too.
1023 pool()->Shutdown();
fdoraybca80902016-09-27 13:41:071024 if (RedirectedToTaskScheduler())
1025 TaskScheduler::GetInstance()->Shutdown();
[email protected]13ecb5e92013-03-07 01:35:371026 pool()->FlushForTesting();
fdoraybca80902016-09-27 13:41:071027
1028 // Verify that all tasks are deleted once the SequencedWorkerPool and the
1029 // TaskScheduler are deleted.
1030 DeletePool();
1031 if (RedirectedToTaskScheduler())
1032 DeleteTaskScheduler();
1033 EXPECT_TRUE(tracker()->HasOneRef());
[email protected]13ecb5e92013-03-07 01:35:371034}
1035
gaba414e992016-08-01 17:29:501036namespace {
bauerb5d315e4b2016-01-07 15:34:081037
gaba414e992016-08-01 17:29:501038void CheckWorkerPoolAndSequenceToken(
1039 const scoped_refptr<SequencedWorkerPool>& expected_pool,
1040 SequencedWorkerPool::SequenceToken expected_token) {
1041 SequencedWorkerPool::SequenceToken token =
gab33a2c412016-07-28 19:05:071042 SequencedWorkerPool::GetSequenceTokenForCurrentThread();
gaba414e992016-08-01 17:29:501043 EXPECT_EQ(expected_token.ToString(), token.ToString());
gab33a2c412016-07-28 19:05:071044
gaba414e992016-08-01 17:29:501045 scoped_refptr<SequencedWorkerPool> pool =
1046 SequencedWorkerPool::GetWorkerPoolForCurrentThread();
1047 EXPECT_EQ(expected_pool, pool);
gab33a2c412016-07-28 19:05:071048}
1049
gaba414e992016-08-01 17:29:501050} // namespace
1051
fdoray37e794792016-09-16 23:19:501052TEST_P(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) {
1053 // GetSequenceTokenForCurrentThread() and GetWorkerPoolForCurrentThread()
1054 // respectively return an invalid token and nullptr from a task posted to a
1055 // SequencedWorkerPool when redirection to TaskScheduler is enabled. These
1056 // methods are only used from SequencedTaskRunnerHandle and
1057 // SequenceCheckerImpl which work fine in TaskScheduler.
fdoraybca80902016-09-27 13:41:071058 if (RedirectedToTaskScheduler())
fdoray37e794792016-09-16 23:19:501059 return;
1060
bauerb8a408722015-10-30 09:05:311061 EnsureAllWorkersCreated();
1062
gaba414e992016-08-01 17:29:501063 // The current thread should have neither a worker pool nor a sequence token.
1064 SequencedWorkerPool::SequenceToken local_token =
1065 SequencedWorkerPool::GetSequenceTokenForCurrentThread();
1066 scoped_refptr<SequencedWorkerPool> local_pool =
1067 SequencedWorkerPool::GetWorkerPoolForCurrentThread();
1068 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString();
1069 EXPECT_FALSE(local_pool);
bauerb8a408722015-10-30 09:05:311070
gaba414e992016-08-01 17:29:501071 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken();
1072 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken();
1073 pool()->PostSequencedWorkerTask(
1074 token1, FROM_HERE,
tzik92b7a422017-04-11 15:00:441075 base::BindOnce(&CheckWorkerPoolAndSequenceToken, pool(), token1));
gaba414e992016-08-01 17:29:501076 pool()->PostSequencedWorkerTask(
1077 token2, FROM_HERE,
tzik92b7a422017-04-11 15:00:441078 base::BindOnce(&CheckWorkerPoolAndSequenceToken, pool(), token2));
bauerb8a408722015-10-30 09:05:311079
sdefresne3f731c72017-05-30 12:52:521080 pool()->PostWorkerTask(
1081 FROM_HERE, base::BindOnce(&CheckWorkerPoolAndSequenceToken, pool(),
1082 SequencedWorkerPool::SequenceToken()));
bauerb8a408722015-10-30 09:05:311083
gaba414e992016-08-01 17:29:501084 pool()->FlushForTesting();
bauerb8a408722015-10-30 09:05:311085}
1086
fdoray37e794792016-09-16 23:19:501087TEST_P(SequencedWorkerPoolTest, ShutsDownCleanWithContinueOnShutdown) {
[email protected]4f60d802013-04-18 05:41:231088 scoped_refptr<SequencedTaskRunner> task_runner =
tapted012326b2015-12-03 04:43:051089 pool()->GetSequencedTaskRunnerWithShutdownBehavior(
1090 pool()->GetSequenceToken(),
[email protected]4f60d802013-04-18 05:41:231091 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
1092
1093 // Upon test exit, should shut down without hanging.
tapted012326b2015-12-03 04:43:051094 pool()->Shutdown();
[email protected]4f60d802013-04-18 05:41:231095}
1096
fdoray37e794792016-09-16 23:19:501097INSTANTIATE_TEST_CASE_P(
1098 NoRedirection,
1099 SequencedWorkerPoolTest,
1100 ::testing::Values(SequencedWorkerPoolRedirection::NONE));
1101INSTANTIATE_TEST_CASE_P(
1102 RedirectionToTaskScheduler,
1103 SequencedWorkerPoolTest,
1104 ::testing::Values(SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER));
1105
[email protected]506fc232012-02-29 01:33:031106class SequencedWorkerPoolTaskRunnerTestDelegate {
1107 public:
1108 SequencedWorkerPoolTaskRunnerTestDelegate() {}
1109
1110 ~SequencedWorkerPoolTaskRunnerTestDelegate() {}
1111
1112 void StartTaskRunner() {
[email protected]71b18fb2012-03-06 14:17:341113 pool_owner_.reset(
1114 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest"));
[email protected]506fc232012-02-29 01:33:031115 }
1116
1117 scoped_refptr<SequencedWorkerPool> GetTaskRunner() {
[email protected]71b18fb2012-03-06 14:17:341118 return pool_owner_->pool();
[email protected]506fc232012-02-29 01:33:031119 }
1120
1121 void StopTaskRunner() {
[email protected]13ecb5e92013-03-07 01:35:371122 // Make sure all tasks are run before shutting down. Delayed tasks are
1123 // not run, they're simply deleted.
[email protected]113d2ac2012-10-02 08:31:571124 pool_owner_->pool()->FlushForTesting();
[email protected]71b18fb2012-03-06 14:17:341125 pool_owner_->pool()->Shutdown();
1126 // Don't reset |pool_owner_| here, as the test may still hold a
1127 // reference to the pool.
[email protected]506fc232012-02-29 01:33:031128 }
1129
[email protected]506fc232012-02-29 01:33:031130 private:
[email protected]71b18fb2012-03-06 14:17:341131 MessageLoop message_loop_;
dcheng093de9b2016-04-04 21:25:511132 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_;
[email protected]506fc232012-02-29 01:33:031133};
1134
1135INSTANTIATE_TYPED_TEST_CASE_P(
1136 SequencedWorkerPool, TaskRunnerTest,
1137 SequencedWorkerPoolTaskRunnerTestDelegate);
dcastagnaef1312d2015-07-24 23:28:111138INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool, TaskRunnerAffinityTest,
1139 SequencedWorkerPoolTaskRunnerTestDelegate);
[email protected]506fc232012-02-29 01:33:031140
[email protected]497ec462012-04-11 22:42:291141class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate {
1142 public:
1143 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() {}
1144
1145 ~SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() {
1146 }
1147
1148 void StartTaskRunner() {
1149 pool_owner_.reset(
1150 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest"));
1151 task_runner_ = pool_owner_->pool()->GetTaskRunnerWithShutdownBehavior(
1152 SequencedWorkerPool::BLOCK_SHUTDOWN);
1153 }
1154
1155 scoped_refptr<TaskRunner> GetTaskRunner() {
1156 return task_runner_;
1157 }
1158
1159 void StopTaskRunner() {
[email protected]13ecb5e92013-03-07 01:35:371160 // Make sure all tasks are run before shutting down. Delayed tasks are
1161 // not run, they're simply deleted.
[email protected]497ec462012-04-11 22:42:291162 pool_owner_->pool()->FlushForTesting();
1163 pool_owner_->pool()->Shutdown();
1164 // Don't reset |pool_owner_| here, as the test may still hold a
1165 // reference to the pool.
1166 }
1167
[email protected]497ec462012-04-11 22:42:291168 private:
1169 MessageLoop message_loop_;
dcheng093de9b2016-04-04 21:25:511170 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_;
[email protected]497ec462012-04-11 22:42:291171 scoped_refptr<TaskRunner> task_runner_;
1172};
1173
1174INSTANTIATE_TYPED_TEST_CASE_P(
1175 SequencedWorkerPoolTaskRunner, TaskRunnerTest,
1176 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate);
dcastagnaef1312d2015-07-24 23:28:111177INSTANTIATE_TYPED_TEST_CASE_P(
1178 SequencedWorkerPoolTaskRunner, TaskRunnerAffinityTest,
1179 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate);
[email protected]497ec462012-04-11 22:42:291180
[email protected]89993aee2012-04-11 08:10:111181class SequencedWorkerPoolSequencedTaskRunnerTestDelegate {
1182 public:
1183 SequencedWorkerPoolSequencedTaskRunnerTestDelegate() {}
1184
1185 ~SequencedWorkerPoolSequencedTaskRunnerTestDelegate() {
1186 }
1187
1188 void StartTaskRunner() {
1189 pool_owner_.reset(new SequencedWorkerPoolOwner(
1190 10, "SequencedWorkerPoolSequencedTaskRunnerTest"));
1191 task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner(
1192 pool_owner_->pool()->GetSequenceToken());
1193 }
1194
1195 scoped_refptr<SequencedTaskRunner> GetTaskRunner() {
1196 return task_runner_;
1197 }
1198
1199 void StopTaskRunner() {
[email protected]13ecb5e92013-03-07 01:35:371200 // Make sure all tasks are run before shutting down. Delayed tasks are
1201 // not run, they're simply deleted.
[email protected]89993aee2012-04-11 08:10:111202 pool_owner_->pool()->FlushForTesting();
1203 pool_owner_->pool()->Shutdown();
1204 // Don't reset |pool_owner_| here, as the test may still hold a
1205 // reference to the pool.
1206 }
1207
[email protected]89993aee2012-04-11 08:10:111208 private:
1209 MessageLoop message_loop_;
dcheng093de9b2016-04-04 21:25:511210 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_;
[email protected]89993aee2012-04-11 08:10:111211 scoped_refptr<SequencedTaskRunner> task_runner_;
1212};
1213
1214INSTANTIATE_TYPED_TEST_CASE_P(
1215 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest,
1216 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
dcastagnaef1312d2015-07-24 23:28:111217INSTANTIATE_TYPED_TEST_CASE_P(
1218 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerAffinityTest,
1219 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
[email protected]89993aee2012-04-11 08:10:111220
1221INSTANTIATE_TYPED_TEST_CASE_P(
1222 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest,
1223 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
dcastagna29e7fc62015-07-31 23:20:061224INSTANTIATE_TYPED_TEST_CASE_P(
1225 SequencedWorkerPoolSequencedTaskRunner,
1226 SequencedTaskRunnerDelayedTest,
1227 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
[email protected]89993aee2012-04-11 08:10:111228
[email protected]506fc232012-02-29 01:33:031229} // namespace
1230
[email protected]098def22012-01-01 05:42:341231} // namespace base