xref: /aosp_15_r20/external/cronet/base/sequence_checker_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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