1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include <memory>
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker #include <utility>
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker_impl.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/sequence_token.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/task/thread_pool.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/threading/simple_thread.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_local.h"
24*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Worker namespace base::internal {
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker namespace {
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker // Runs a callback on another thread.
31*6777b538SAndroid Build Coastguard Worker class RunCallbackThread : public SimpleThread {
32*6777b538SAndroid Build Coastguard Worker public:
RunCallbackThread(OnceClosure callback)33*6777b538SAndroid Build Coastguard Worker explicit RunCallbackThread(OnceClosure callback)
34*6777b538SAndroid Build Coastguard Worker : SimpleThread("RunCallbackThread"), callback_(std::move(callback)) {
35*6777b538SAndroid Build Coastguard Worker Start();
36*6777b538SAndroid Build Coastguard Worker Join();
37*6777b538SAndroid Build Coastguard Worker }
38*6777b538SAndroid Build Coastguard Worker RunCallbackThread(const RunCallbackThread&) = delete;
39*6777b538SAndroid Build Coastguard Worker RunCallbackThread& operator=(const RunCallbackThread&) = delete;
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker private:
42*6777b538SAndroid Build Coastguard Worker // SimpleThread:
Run()43*6777b538SAndroid Build Coastguard Worker void Run() override { std::move(callback_).Run(); }
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker OnceClosure callback_;
46*6777b538SAndroid Build Coastguard Worker };
47*6777b538SAndroid Build Coastguard Worker
ExpectCalledOnValidSequence(SequenceCheckerImpl * sequence_checker)48*6777b538SAndroid Build Coastguard Worker void ExpectCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
49*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(sequence_checker);
50*6777b538SAndroid Build Coastguard Worker
51*6777b538SAndroid Build Coastguard Worker // This should bind |sequence_checker| to the current sequence if it wasn't
52*6777b538SAndroid Build Coastguard Worker // already bound to a sequence.
53*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Worker // Since |sequence_checker| is now bound to the current sequence, another call
56*6777b538SAndroid Build Coastguard Worker // to CalledOnValidSequence() should return true.
57*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
58*6777b538SAndroid Build Coastguard Worker }
59*6777b538SAndroid Build Coastguard Worker
ExpectNotCalledOnValidSequence(SequenceCheckerImpl * sequence_checker)60*6777b538SAndroid Build Coastguard Worker void ExpectNotCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
61*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(sequence_checker);
62*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker } // namespace
66*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,NoTaskScope)67*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, NoTaskScope) {
68*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
69*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
70*6777b538SAndroid Build Coastguard Worker }
71*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,TaskScope)72*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, TaskScope) {
73*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
74*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
75*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
76*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
77*6777b538SAndroid Build Coastguard Worker }
78*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,TaskScopeThreadBound)79*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, TaskScopeThreadBound) {
80*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
81*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/true);
82*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
83*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DifferentThreadNoTaskScope)86*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DifferentThreadNoTaskScope) {
87*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
88*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread(
89*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidSequence, Unretained(&sequence_checker)));
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DifferentThreadDifferentSequenceToken)92*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DifferentThreadDifferentSequenceToken) {
93*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
94*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread(BindLambdaForTesting([&]() {
95*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
96*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
97*6777b538SAndroid Build Coastguard Worker ExpectNotCalledOnValidSequence(&sequence_checker);
98*6777b538SAndroid Build Coastguard Worker }));
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DifferentThreadDifferentSequenceTokenThreadBound)101*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DifferentThreadDifferentSequenceTokenThreadBound) {
102*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
103*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread(BindLambdaForTesting([&]() {
104*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
105*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/true);
106*6777b538SAndroid Build Coastguard Worker ExpectNotCalledOnValidSequence(&sequence_checker);
107*6777b538SAndroid Build Coastguard Worker }));
108*6777b538SAndroid Build Coastguard Worker }
109*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DifferentThreadSameSequenceToken)110*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DifferentThreadSameSequenceToken) {
111*6777b538SAndroid Build Coastguard Worker const SequenceToken token = SequenceToken::Create();
112*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(token, /* is_thread_bound=*/false);
113*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
114*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread(BindLambdaForTesting([&]() {
115*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(token, /* is_thread_bound=*/false);
116*6777b538SAndroid Build Coastguard Worker ExpectCalledOnValidSequence(&sequence_checker);
117*6777b538SAndroid Build Coastguard Worker }));
118*6777b538SAndroid Build Coastguard Worker }
119*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DifferentThreadSameSequenceTokenThreadBound)120*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DifferentThreadSameSequenceTokenThreadBound) {
121*6777b538SAndroid Build Coastguard Worker // Note: A callback running synchronously in `RunOrPostTask()` may have a
122*6777b538SAndroid Build Coastguard Worker // non-thread-bound `TaskScope` associated with the same `SequenceToken` as
123*6777b538SAndroid Build Coastguard Worker // another thread-bound `TaskScope`. This test recreates this case.
124*6777b538SAndroid Build Coastguard Worker const SequenceToken token = SequenceToken::Create();
125*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(token, /* is_thread_bound=*/true);
126*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
127*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread(BindLambdaForTesting([&]() {
128*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(token, /* is_thread_bound=*/false);
129*6777b538SAndroid Build Coastguard Worker ExpectCalledOnValidSequence(&sequence_checker);
130*6777b538SAndroid Build Coastguard Worker }));
131*6777b538SAndroid Build Coastguard Worker }
132*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,SameThreadDifferentSequenceToken)133*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, SameThreadDifferentSequenceToken) {
134*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SequenceCheckerImpl> sequence_checker;
135*6777b538SAndroid Build Coastguard Worker
136*6777b538SAndroid Build Coastguard Worker {
137*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
138*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
139*6777b538SAndroid Build Coastguard Worker sequence_checker = std::make_unique<SequenceCheckerImpl>();
140*6777b538SAndroid Build Coastguard Worker }
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker {
143*6777b538SAndroid Build Coastguard Worker // Different SequenceToken.
144*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
145*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
146*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
147*6777b538SAndroid Build Coastguard Worker }
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker // No explicit SequenceToken.
150*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
151*6777b538SAndroid Build Coastguard Worker }
152*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DetachFromSequence)153*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DetachFromSequence) {
154*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SequenceCheckerImpl> sequence_checker;
155*6777b538SAndroid Build Coastguard Worker
156*6777b538SAndroid Build Coastguard Worker {
157*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
158*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
159*6777b538SAndroid Build Coastguard Worker sequence_checker = std::make_unique<SequenceCheckerImpl>();
160*6777b538SAndroid Build Coastguard Worker }
161*6777b538SAndroid Build Coastguard Worker
162*6777b538SAndroid Build Coastguard Worker sequence_checker->DetachFromSequence();
163*6777b538SAndroid Build Coastguard Worker
164*6777b538SAndroid Build Coastguard Worker {
165*6777b538SAndroid Build Coastguard Worker // Verify that CalledOnValidSequence() returns true when called with
166*6777b538SAndroid Build Coastguard Worker // a different sequence token after a call to DetachFromSequence().
167*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
168*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
169*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
170*6777b538SAndroid Build Coastguard Worker }
171*6777b538SAndroid Build Coastguard Worker }
172*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DetachFromSequenceNoSequenceToken)173*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DetachFromSequenceNoSequenceToken) {
174*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
175*6777b538SAndroid Build Coastguard Worker sequence_checker.DetachFromSequence();
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker // Verify that CalledOnValidSequence() returns true when called on a
178*6777b538SAndroid Build Coastguard Worker // different thread after a call to DetachFromSequence().
179*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread(
180*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)));
181*6777b538SAndroid Build Coastguard Worker
182*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(sequence_checker.CalledOnValidSequence());
183*6777b538SAndroid Build Coastguard Worker }
184*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,Move)185*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, Move) {
186*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl initial;
187*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(initial.CalledOnValidSequence());
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl move_constructed(std::move(initial));
190*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(move_constructed.CalledOnValidSequence());
191*6777b538SAndroid Build Coastguard Worker
192*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl move_assigned;
193*6777b538SAndroid Build Coastguard Worker move_assigned = std::move(move_constructed);
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker // The two SequenceCheckerImpls moved from should be able to rebind to another
196*6777b538SAndroid Build Coastguard Worker // sequence.
197*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread1(
198*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidSequence, Unretained(&initial)));
199*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread2(
200*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidSequence, Unretained(&move_constructed)));
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard Worker // But the latest one shouldn't be able to run on another sequence.
203*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread(
204*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidSequence, Unretained(&move_assigned)));
205*6777b538SAndroid Build Coastguard Worker
206*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(move_assigned.CalledOnValidSequence());
207*6777b538SAndroid Build Coastguard Worker }
208*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,MoveAssignIntoDetached)209*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, MoveAssignIntoDetached) {
210*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl initial;
211*6777b538SAndroid Build Coastguard Worker
212*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl move_assigned;
213*6777b538SAndroid Build Coastguard Worker move_assigned.DetachFromSequence();
214*6777b538SAndroid Build Coastguard Worker move_assigned = std::move(initial);
215*6777b538SAndroid Build Coastguard Worker
216*6777b538SAndroid Build Coastguard Worker // |initial| is detached after move.
217*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread1(
218*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidSequence, Unretained(&initial)));
219*6777b538SAndroid Build Coastguard Worker
220*6777b538SAndroid Build Coastguard Worker // |move_assigned| should be associated with the main thread.
221*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread2(
222*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidSequence, Unretained(&move_assigned)));
223*6777b538SAndroid Build Coastguard Worker
224*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(move_assigned.CalledOnValidSequence());
225*6777b538SAndroid Build Coastguard Worker }
226*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,MoveFromDetachedRebinds)227*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, MoveFromDetachedRebinds) {
228*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl initial;
229*6777b538SAndroid Build Coastguard Worker initial.DetachFromSequence();
230*6777b538SAndroid Build Coastguard Worker
231*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl moved_into(std::move(initial));
232*6777b538SAndroid Build Coastguard Worker
233*6777b538SAndroid Build Coastguard Worker // |initial| is still detached after move.
234*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread1(
235*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidSequence, Unretained(&initial)));
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker // |moved_into| is bound to the current sequence as part of the move.
238*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread2(
239*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidSequence, Unretained(&moved_into)));
240*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(moved_into.CalledOnValidSequence());
241*6777b538SAndroid Build Coastguard Worker }
242*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,MoveOffSequenceBanned)243*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, MoveOffSequenceBanned) {
244*6777b538SAndroid Build Coastguard Worker GTEST_FLAG_SET(death_test_style, "threadsafe");
245*6777b538SAndroid Build Coastguard Worker
246*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl other_sequence;
247*6777b538SAndroid Build Coastguard Worker other_sequence.DetachFromSequence();
248*6777b538SAndroid Build Coastguard Worker RunCallbackThread thread(
249*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidSequence, Unretained(&other_sequence)));
250*6777b538SAndroid Build Coastguard Worker
251*6777b538SAndroid Build Coastguard Worker EXPECT_DCHECK_DEATH(
252*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl main_sequence(std::move(other_sequence)));
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker
TEST(SequenceCheckerMacroTest,Macros)255*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerMacroTest, Macros) {
256*6777b538SAndroid Build Coastguard Worker auto scope = std::make_unique<TaskScope>(SequenceToken::Create(),
257*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
258*6777b538SAndroid Build Coastguard Worker SEQUENCE_CHECKER(my_sequence_checker);
259*6777b538SAndroid Build Coastguard Worker
260*6777b538SAndroid Build Coastguard Worker {
261*6777b538SAndroid Build Coastguard Worker // Don't expect a DCHECK death when a SequenceChecker is used on the right
262*6777b538SAndroid Build Coastguard Worker // sequence.
263*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker);
264*6777b538SAndroid Build Coastguard Worker }
265*6777b538SAndroid Build Coastguard Worker scope.reset();
266*6777b538SAndroid Build Coastguard Worker
267*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
268*6777b538SAndroid Build Coastguard Worker // Expect DCHECK death when used on a different sequence.
269*6777b538SAndroid Build Coastguard Worker EXPECT_DCHECK_DEATH(
270*6777b538SAndroid Build Coastguard Worker { DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker); });
271*6777b538SAndroid Build Coastguard Worker #else
272*6777b538SAndroid Build Coastguard Worker // Happily no-ops on non-dcheck builds.
273*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker);
274*6777b538SAndroid Build Coastguard Worker #endif
275*6777b538SAndroid Build Coastguard Worker
276*6777b538SAndroid Build Coastguard Worker DETACH_FROM_SEQUENCE(my_sequence_checker);
277*6777b538SAndroid Build Coastguard Worker
278*6777b538SAndroid Build Coastguard Worker // Don't expect a DCHECK death when a SequenceChecker is used for the first
279*6777b538SAndroid Build Coastguard Worker // time after having been detached.
280*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker);
281*6777b538SAndroid Build Coastguard Worker }
282*6777b538SAndroid Build Coastguard Worker
283*6777b538SAndroid Build Coastguard Worker // Owns a SequenceCheckerImpl, and asserts that CalledOnValidSequence() is valid
284*6777b538SAndroid Build Coastguard Worker // in ~SequenceCheckerOwner.
285*6777b538SAndroid Build Coastguard Worker class SequenceCheckerOwner {
286*6777b538SAndroid Build Coastguard Worker public:
SequenceCheckerOwner(SequenceCheckerImpl * other_checker)287*6777b538SAndroid Build Coastguard Worker explicit SequenceCheckerOwner(SequenceCheckerImpl* other_checker)
288*6777b538SAndroid Build Coastguard Worker : other_checker_(other_checker) {}
289*6777b538SAndroid Build Coastguard Worker SequenceCheckerOwner(const SequenceCheckerOwner&) = delete;
290*6777b538SAndroid Build Coastguard Worker SequenceCheckerOwner& operator=(const SequenceCheckerOwner&) = delete;
~SequenceCheckerOwner()291*6777b538SAndroid Build Coastguard Worker ~SequenceCheckerOwner() {
292*6777b538SAndroid Build Coastguard Worker // Check passes on TLS destruction.
293*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(checker_.CalledOnValidSequence());
294*6777b538SAndroid Build Coastguard Worker
295*6777b538SAndroid Build Coastguard Worker // Check also passes on TLS destruction after move assignment.
296*6777b538SAndroid Build Coastguard Worker *other_checker_ = std::move(checker_);
297*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(other_checker_->CalledOnValidSequence());
298*6777b538SAndroid Build Coastguard Worker }
299*6777b538SAndroid Build Coastguard Worker
300*6777b538SAndroid Build Coastguard Worker private:
301*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl checker_;
302*6777b538SAndroid Build Coastguard Worker raw_ptr<SequenceCheckerImpl> other_checker_;
303*6777b538SAndroid Build Coastguard Worker };
304*6777b538SAndroid Build Coastguard Worker
305*6777b538SAndroid Build Coastguard Worker // Verifies SequenceCheckerImpl::CalledOnValidSequence() returns true if called
306*6777b538SAndroid Build Coastguard Worker // during thread destruction.
TEST(SequenceCheckerTest,FromThreadDestruction)307*6777b538SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, FromThreadDestruction) {
308*6777b538SAndroid Build Coastguard Worker SequenceChecker::EnableStackLogging();
309*6777b538SAndroid Build Coastguard Worker
310*6777b538SAndroid Build Coastguard Worker SequenceCheckerImpl other_checker;
311*6777b538SAndroid Build Coastguard Worker ThreadLocalOwnedPointer<SequenceCheckerOwner> thread_local_owner;
312*6777b538SAndroid Build Coastguard Worker {
313*6777b538SAndroid Build Coastguard Worker test::TaskEnvironment task_environment;
314*6777b538SAndroid Build Coastguard Worker auto task_runner = ThreadPool::CreateSequencedTaskRunner({});
315*6777b538SAndroid Build Coastguard Worker task_runner->PostTask(
316*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindLambdaForTesting([&]() {
317*6777b538SAndroid Build Coastguard Worker thread_local_owner.Set(
318*6777b538SAndroid Build Coastguard Worker std::make_unique<SequenceCheckerOwner>(&other_checker));
319*6777b538SAndroid Build Coastguard Worker }));
320*6777b538SAndroid Build Coastguard Worker task_runner = nullptr;
321*6777b538SAndroid Build Coastguard Worker task_environment.RunUntilIdle();
322*6777b538SAndroid Build Coastguard Worker }
323*6777b538SAndroid Build Coastguard Worker }
324*6777b538SAndroid Build Coastguard Worker
325*6777b538SAndroid Build Coastguard Worker } // namespace base::internal
326