1*635a8641SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/sequence_checker.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker #include <string>
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/bind_helpers.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/callback_forward.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/sequence_token.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/threading/simple_thread.h"
20*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
21*635a8641SAndroid Build Coastguard Worker
22*635a8641SAndroid Build Coastguard Worker namespace base {
23*635a8641SAndroid Build Coastguard Worker
24*635a8641SAndroid Build Coastguard Worker namespace {
25*635a8641SAndroid Build Coastguard Worker
26*635a8641SAndroid Build Coastguard Worker // Runs a callback on another thread.
27*635a8641SAndroid Build Coastguard Worker class RunCallbackThread : public SimpleThread {
28*635a8641SAndroid Build Coastguard Worker public:
RunCallbackThread(const Closure & callback)29*635a8641SAndroid Build Coastguard Worker explicit RunCallbackThread(const Closure& callback)
30*635a8641SAndroid Build Coastguard Worker : SimpleThread("RunCallbackThread"), callback_(callback) {
31*635a8641SAndroid Build Coastguard Worker Start();
32*635a8641SAndroid Build Coastguard Worker Join();
33*635a8641SAndroid Build Coastguard Worker }
34*635a8641SAndroid Build Coastguard Worker
35*635a8641SAndroid Build Coastguard Worker private:
36*635a8641SAndroid Build Coastguard Worker // SimpleThread:
Run()37*635a8641SAndroid Build Coastguard Worker void Run() override { callback_.Run(); }
38*635a8641SAndroid Build Coastguard Worker
39*635a8641SAndroid Build Coastguard Worker const Closure callback_;
40*635a8641SAndroid Build Coastguard Worker
41*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(RunCallbackThread);
42*635a8641SAndroid Build Coastguard Worker };
43*635a8641SAndroid Build Coastguard Worker
ExpectCalledOnValidSequence(SequenceCheckerImpl * sequence_checker)44*635a8641SAndroid Build Coastguard Worker void ExpectCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
45*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(sequence_checker);
46*635a8641SAndroid Build Coastguard Worker
47*635a8641SAndroid Build Coastguard Worker // This should bind |sequence_checker| to the current sequence if it wasn't
48*635a8641SAndroid Build Coastguard Worker // already bound to a sequence.
49*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
50*635a8641SAndroid Build Coastguard Worker
51*635a8641SAndroid Build Coastguard Worker // Since |sequence_checker| is now bound to the current sequence, another call
52*635a8641SAndroid Build Coastguard Worker // to CalledOnValidSequence() should return true.
53*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
54*635a8641SAndroid Build Coastguard Worker }
55*635a8641SAndroid Build Coastguard Worker
ExpectCalledOnValidSequenceWithSequenceToken(SequenceCheckerImpl * sequence_checker,SequenceToken sequence_token)56*635a8641SAndroid Build Coastguard Worker void ExpectCalledOnValidSequenceWithSequenceToken(
57*635a8641SAndroid Build Coastguard Worker SequenceCheckerImpl* sequence_checker,
58*635a8641SAndroid Build Coastguard Worker SequenceToken sequence_token) {
59*635a8641SAndroid Build Coastguard Worker ScopedSetSequenceTokenForCurrentThread
60*635a8641SAndroid Build Coastguard Worker scoped_set_sequence_token_for_current_thread(sequence_token);
61*635a8641SAndroid Build Coastguard Worker ExpectCalledOnValidSequence(sequence_checker);
62*635a8641SAndroid Build Coastguard Worker }
63*635a8641SAndroid Build Coastguard Worker
ExpectNotCalledOnValidSequence(SequenceCheckerImpl * sequence_checker)64*635a8641SAndroid Build Coastguard Worker void ExpectNotCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
65*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(sequence_checker);
66*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
67*635a8641SAndroid Build Coastguard Worker }
68*635a8641SAndroid Build Coastguard Worker
69*635a8641SAndroid Build Coastguard Worker } // namespace
70*635a8641SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,CallsAllowedOnSameThreadNoSequenceToken)71*635a8641SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, CallsAllowedOnSameThreadNoSequenceToken) {
72*635a8641SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
73*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
74*635a8641SAndroid Build Coastguard Worker }
75*635a8641SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,CallsAllowedOnSameThreadSameSequenceToken)76*635a8641SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, CallsAllowedOnSameThreadSameSequenceToken) {
77*635a8641SAndroid Build Coastguard Worker ScopedSetSequenceTokenForCurrentThread
78*635a8641SAndroid Build Coastguard Worker scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
79*635a8641SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
80*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
81*635a8641SAndroid Build Coastguard Worker }
82*635a8641SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,CallsDisallowedOnDifferentThreadsNoSequenceToken)83*635a8641SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, CallsDisallowedOnDifferentThreadsNoSequenceToken) {
84*635a8641SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
85*635a8641SAndroid Build Coastguard Worker RunCallbackThread thread(
86*635a8641SAndroid Build Coastguard Worker Bind(&ExpectNotCalledOnValidSequence, Unretained(&sequence_checker)));
87*635a8641SAndroid Build Coastguard Worker }
88*635a8641SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,CallsAllowedOnDifferentThreadsSameSequenceToken)89*635a8641SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, CallsAllowedOnDifferentThreadsSameSequenceToken) {
90*635a8641SAndroid Build Coastguard Worker const SequenceToken sequence_token(SequenceToken::Create());
91*635a8641SAndroid Build Coastguard Worker
92*635a8641SAndroid Build Coastguard Worker ScopedSetSequenceTokenForCurrentThread
93*635a8641SAndroid Build Coastguard Worker scoped_set_sequence_token_for_current_thread(sequence_token);
94*635a8641SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
95*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
96*635a8641SAndroid Build Coastguard Worker
97*635a8641SAndroid Build Coastguard Worker RunCallbackThread thread(Bind(&ExpectCalledOnValidSequenceWithSequenceToken,
98*635a8641SAndroid Build Coastguard Worker Unretained(&sequence_checker), sequence_token));
99*635a8641SAndroid Build Coastguard Worker }
100*635a8641SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,CallsDisallowedOnSameThreadDifferentSequenceToken)101*635a8641SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, CallsDisallowedOnSameThreadDifferentSequenceToken) {
102*635a8641SAndroid Build Coastguard Worker std::unique_ptr<SequenceCheckerImpl> sequence_checker;
103*635a8641SAndroid Build Coastguard Worker
104*635a8641SAndroid Build Coastguard Worker {
105*635a8641SAndroid Build Coastguard Worker ScopedSetSequenceTokenForCurrentThread
106*635a8641SAndroid Build Coastguard Worker scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
107*635a8641SAndroid Build Coastguard Worker sequence_checker.reset(new SequenceCheckerImpl);
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker
110*635a8641SAndroid Build Coastguard Worker {
111*635a8641SAndroid Build Coastguard Worker // Different SequenceToken.
112*635a8641SAndroid Build Coastguard Worker ScopedSetSequenceTokenForCurrentThread
113*635a8641SAndroid Build Coastguard Worker scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
114*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
115*635a8641SAndroid Build Coastguard Worker }
116*635a8641SAndroid Build Coastguard Worker
117*635a8641SAndroid Build Coastguard Worker // No SequenceToken.
118*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
119*635a8641SAndroid Build Coastguard Worker }
120*635a8641SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DetachFromSequence)121*635a8641SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DetachFromSequence) {
122*635a8641SAndroid Build Coastguard Worker std::unique_ptr<SequenceCheckerImpl> sequence_checker;
123*635a8641SAndroid Build Coastguard Worker
124*635a8641SAndroid Build Coastguard Worker {
125*635a8641SAndroid Build Coastguard Worker ScopedSetSequenceTokenForCurrentThread
126*635a8641SAndroid Build Coastguard Worker scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
127*635a8641SAndroid Build Coastguard Worker sequence_checker.reset(new SequenceCheckerImpl);
128*635a8641SAndroid Build Coastguard Worker }
129*635a8641SAndroid Build Coastguard Worker
130*635a8641SAndroid Build Coastguard Worker sequence_checker->DetachFromSequence();
131*635a8641SAndroid Build Coastguard Worker
132*635a8641SAndroid Build Coastguard Worker {
133*635a8641SAndroid Build Coastguard Worker // Verify that CalledOnValidSequence() returns true when called with
134*635a8641SAndroid Build Coastguard Worker // a different sequence token after a call to DetachFromSequence().
135*635a8641SAndroid Build Coastguard Worker ScopedSetSequenceTokenForCurrentThread
136*635a8641SAndroid Build Coastguard Worker scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
137*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
138*635a8641SAndroid Build Coastguard Worker }
139*635a8641SAndroid Build Coastguard Worker }
140*635a8641SAndroid Build Coastguard Worker
TEST(SequenceCheckerTest,DetachFromSequenceNoSequenceToken)141*635a8641SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DetachFromSequenceNoSequenceToken) {
142*635a8641SAndroid Build Coastguard Worker SequenceCheckerImpl sequence_checker;
143*635a8641SAndroid Build Coastguard Worker sequence_checker.DetachFromSequence();
144*635a8641SAndroid Build Coastguard Worker
145*635a8641SAndroid Build Coastguard Worker // Verify that CalledOnValidSequence() returns true when called on a
146*635a8641SAndroid Build Coastguard Worker // different thread after a call to DetachFromSequence().
147*635a8641SAndroid Build Coastguard Worker RunCallbackThread thread(
148*635a8641SAndroid Build Coastguard Worker Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)));
149*635a8641SAndroid Build Coastguard Worker
150*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(sequence_checker.CalledOnValidSequence());
151*635a8641SAndroid Build Coastguard Worker }
152*635a8641SAndroid Build Coastguard Worker
TEST(SequenceCheckerMacroTest,Macros)153*635a8641SAndroid Build Coastguard Worker TEST(SequenceCheckerMacroTest, Macros) {
154*635a8641SAndroid Build Coastguard Worker auto scope = std::make_unique<ScopedSetSequenceTokenForCurrentThread>(
155*635a8641SAndroid Build Coastguard Worker SequenceToken::Create());
156*635a8641SAndroid Build Coastguard Worker SEQUENCE_CHECKER(my_sequence_checker);
157*635a8641SAndroid Build Coastguard Worker
158*635a8641SAndroid Build Coastguard Worker // Don't expect a DCHECK death when a SequenceChecker is used on the right
159*635a8641SAndroid Build Coastguard Worker // sequence.
160*635a8641SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
161*635a8641SAndroid Build Coastguard Worker
162*635a8641SAndroid Build Coastguard Worker scope.reset();
163*635a8641SAndroid Build Coastguard Worker
164*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
165*635a8641SAndroid Build Coastguard Worker // Expect DCHECK death when used on a different sequence.
166*635a8641SAndroid Build Coastguard Worker EXPECT_DCHECK_DEATH({
167*635a8641SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
168*635a8641SAndroid Build Coastguard Worker });
169*635a8641SAndroid Build Coastguard Worker #else
170*635a8641SAndroid Build Coastguard Worker // Happily no-ops on non-dcheck builds.
171*635a8641SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
172*635a8641SAndroid Build Coastguard Worker #endif
173*635a8641SAndroid Build Coastguard Worker
174*635a8641SAndroid Build Coastguard Worker DETACH_FROM_SEQUENCE(my_sequence_checker);
175*635a8641SAndroid Build Coastguard Worker
176*635a8641SAndroid Build Coastguard Worker // Don't expect a DCHECK death when a SequenceChecker is used for the first
177*635a8641SAndroid Build Coastguard Worker // time after having been detached.
178*635a8641SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
179*635a8641SAndroid Build Coastguard Worker }
180*635a8641SAndroid Build Coastguard Worker
181*635a8641SAndroid Build Coastguard Worker } // namespace base
182