blob: 7451e1d7a421fbdab915429fc15ede77461990eb [file] [log] [blame]
tzikedbd3862016-08-15 15:12:121// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/sequenced_task_runner.h"
6
7#include "base/bind.h"
gab98dee772017-06-07 15:49:038#include "base/gtest_prod_util.h"
tzikedbd3862016-08-15 15:12:129#include "base/message_loop/message_loop.h"
10#include "base/run_loop.h"
11#include "base/threading/thread.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace base {
15namespace {
16
gab98dee772017-06-07 15:49:0317class FlagOnDelete {
18 public:
19 FlagOnDelete(bool* deleted,
20 scoped_refptr<SequencedTaskRunner> expected_deletion_sequence)
21 : deleted_(deleted),
22 expected_deletion_sequence_(std::move(expected_deletion_sequence)) {}
23
24 private:
25 friend class DeleteHelper<FlagOnDelete>;
26 FRIEND_TEST_ALL_PREFIXES(SequencedTaskRunnerTest,
27 OnTaskRunnerDeleterTargetStoppedEarly);
28
29 ~FlagOnDelete() {
30 EXPECT_FALSE(*deleted_);
31 *deleted_ = true;
32 if (expected_deletion_sequence_)
33 EXPECT_TRUE(expected_deletion_sequence_->RunsTasksInCurrentSequence());
tzikedbd3862016-08-15 15:12:1234 }
35
gab98dee772017-06-07 15:49:0336 bool* deleted_;
37 const scoped_refptr<SequencedTaskRunner> expected_deletion_sequence_;
38
39 DISALLOW_COPY_AND_ASSIGN(FlagOnDelete);
tzikedbd3862016-08-15 15:12:1240};
41
gab98dee772017-06-07 15:49:0342class SequencedTaskRunnerTest : public testing::Test {
43 protected:
44 SequencedTaskRunnerTest() : foreign_thread_("foreign") {}
tzikedbd3862016-08-15 15:12:1245
gab98dee772017-06-07 15:49:0346 void SetUp() override {
47 main_runner_ = message_loop_.task_runner();
tzikedbd3862016-08-15 15:12:1248
gab98dee772017-06-07 15:49:0349 foreign_thread_.Start();
50 foreign_runner_ = foreign_thread_.task_runner();
51 }
tzikedbd3862016-08-15 15:12:1252
gab98dee772017-06-07 15:49:0353 scoped_refptr<SequencedTaskRunner> main_runner_;
54 scoped_refptr<SequencedTaskRunner> foreign_runner_;
tzikedbd3862016-08-15 15:12:1255
gab98dee772017-06-07 15:49:0356 Thread foreign_thread_;
57
58 private:
59 MessageLoop message_loop_;
60
61 DISALLOW_COPY_AND_ASSIGN(SequencedTaskRunnerTest);
62};
63
64using SequenceBoundUniquePtr =
65 std::unique_ptr<FlagOnDelete, OnTaskRunnerDeleter>;
66
67TEST_F(SequencedTaskRunnerTest, OnTaskRunnerDeleterOnMainThread) {
68 bool deleted_on_main_thread = false;
69 SequenceBoundUniquePtr ptr(
70 new FlagOnDelete(&deleted_on_main_thread, main_runner_),
71 OnTaskRunnerDeleter(main_runner_));
72 EXPECT_FALSE(deleted_on_main_thread);
73 foreign_runner_->PostTask(
tzik92b7a422017-04-11 15:00:4474 FROM_HERE, BindOnce([](SequenceBoundUniquePtr) {}, Passed(&ptr)));
tzikedbd3862016-08-15 15:12:1275
76 {
77 RunLoop run_loop;
gab98dee772017-06-07 15:49:0378 foreign_runner_->PostTaskAndReply(FROM_HERE, BindOnce([] {}),
79 run_loop.QuitClosure());
tzikedbd3862016-08-15 15:12:1280 run_loop.Run();
81 }
gab98dee772017-06-07 15:49:0382 EXPECT_TRUE(deleted_on_main_thread);
tzikedbd3862016-08-15 15:12:1283}
84
gab98dee772017-06-07 15:49:0385TEST_F(SequencedTaskRunnerTest, OnTaskRunnerDeleterTargetStoppedEarly) {
86 bool deleted_on_main_thread = false;
87 FlagOnDelete* raw = new FlagOnDelete(&deleted_on_main_thread, main_runner_);
88 SequenceBoundUniquePtr ptr(raw, OnTaskRunnerDeleter(foreign_runner_));
89 EXPECT_FALSE(deleted_on_main_thread);
90
91 // Stopping the target ahead of deleting |ptr| should make its
92 // OnTaskRunnerDeleter no-op.
93 foreign_thread_.Stop();
94 ptr = nullptr;
95 EXPECT_FALSE(deleted_on_main_thread);
96
97 delete raw;
98 EXPECT_TRUE(deleted_on_main_thread);
99}
100
101} // namespace
tzikedbd3862016-08-15 15:12:12102} // namespace base