blob: a36c46787280dab3f5f8184c671d00402f665e3b [file] [log] [blame]
tommycli@chromium.org623e16c2013-07-31 04:26:40 +09001// Copyright 2013 The Chromium Authors. All rights reserved.
akalin@chromium.org4fb2deb2012-12-28 04:58:00 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
gabbe9beea2017-05-11 13:15:59 +09005#include "base/sequence_checker.h"
6
avia6a6a682015-12-27 07:15:14 +09007#include <stddef.h>
8
dchengcc8e4d82016-04-05 06:25:51 +09009#include <memory>
fdoray4bcf1082016-07-27 07:28:45 +090010#include <string>
danakj800d2ea2015-11-25 14:29:58 +090011
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090012#include "base/bind.h"
13#include "base/bind_helpers.h"
fdoray4bcf1082016-07-27 07:28:45 +090014#include "base/callback_forward.h"
avia6a6a682015-12-27 07:15:14 +090015#include "base/macros.h"
fdoray4bcf1082016-07-27 07:28:45 +090016#include "base/message_loop/message_loop.h"
fdoray4bcf1082016-07-27 07:28:45 +090017#include "base/sequence_token.h"
skyostil97aefe12015-05-01 04:06:15 +090018#include "base/single_thread_task_runner.h"
gabbe9beea2017-05-11 13:15:59 +090019#include "base/test/gtest_util.h"
fdoray4bcf1082016-07-27 07:28:45 +090020#include "base/threading/simple_thread.h"
dewittj@chromium.orgfadd9342013-07-27 02:10:02 +090021#include "testing/gtest/include/gtest/gtest.h"
tommycli@chromium.org755085a2013-07-26 23:23:56 +090022
akalin@chromium.org4fb2deb2012-12-28 04:58:00 +090023namespace base {
24
25namespace {
26
fdoray4bcf1082016-07-27 07:28:45 +090027// Runs a callback on another thread.
28class RunCallbackThread : public SimpleThread {
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090029 public:
fdoray4bcf1082016-07-27 07:28:45 +090030 explicit RunCallbackThread(const Closure& callback)
31 : SimpleThread("RunCallbackThread"), callback_(callback) {
32 Start();
33 Join();
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090034 }
35
36 private:
fdoray4bcf1082016-07-27 07:28:45 +090037 // SimpleThread:
38 void Run() override { callback_.Run(); }
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090039
fdoray4bcf1082016-07-27 07:28:45 +090040 const Closure callback_;
41
42 DISALLOW_COPY_AND_ASSIGN(RunCallbackThread);
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090043};
44
fdoraye4a58272016-07-29 11:30:16 +090045void ExpectCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
fdoray4bcf1082016-07-27 07:28:45 +090046 ASSERT_TRUE(sequence_checker);
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090047
fdoray4bcf1082016-07-27 07:28:45 +090048 // This should bind |sequence_checker| to the current sequence if it wasn't
49 // already bound to a sequence.
fdoraye4a58272016-07-29 11:30:16 +090050 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090051
fdoray4bcf1082016-07-27 07:28:45 +090052 // Since |sequence_checker| is now bound to the current sequence, another call
fdoraye4a58272016-07-29 11:30:16 +090053 // to CalledOnValidSequence() should return true.
54 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
akalin@chromium.org4fb2deb2012-12-28 04:58:00 +090055}
56
fdoraye4a58272016-07-29 11:30:16 +090057void ExpectCalledOnValidSequenceWithSequenceToken(
fdoray4bcf1082016-07-27 07:28:45 +090058 SequenceCheckerImpl* sequence_checker,
59 SequenceToken sequence_token) {
60 ScopedSetSequenceTokenForCurrentThread
61 scoped_set_sequence_token_for_current_thread(sequence_token);
fdoraye4a58272016-07-29 11:30:16 +090062 ExpectCalledOnValidSequence(sequence_checker);
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090063}
64
fdoraye4a58272016-07-29 11:30:16 +090065void ExpectNotCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
fdoray4bcf1082016-07-27 07:28:45 +090066 ASSERT_TRUE(sequence_checker);
fdoraye4a58272016-07-29 11:30:16 +090067 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090068}
69
akalin@chromium.org4fb2deb2012-12-28 04:58:00 +090070} // namespace
71
Francois Doray3c2d2fd2018-02-22 21:48:38 +090072TEST(SequenceCheckerTest, CallsAllowedOnSameThreadNoSequenceToken) {
fdoray4bcf1082016-07-27 07:28:45 +090073 SequenceCheckerImpl sequence_checker;
fdoraye4a58272016-07-29 11:30:16 +090074 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +090075}
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090076
Francois Doray3c2d2fd2018-02-22 21:48:38 +090077TEST(SequenceCheckerTest, CallsAllowedOnSameThreadSameSequenceToken) {
fdoray4bcf1082016-07-27 07:28:45 +090078 ScopedSetSequenceTokenForCurrentThread
79 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
80 SequenceCheckerImpl sequence_checker;
fdoraye4a58272016-07-29 11:30:16 +090081 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +090082}
83
Francois Doray3c2d2fd2018-02-22 21:48:38 +090084TEST(SequenceCheckerTest, CallsDisallowedOnDifferentThreadsNoSequenceToken) {
fdoray4bcf1082016-07-27 07:28:45 +090085 SequenceCheckerImpl sequence_checker;
fdoraye4a58272016-07-29 11:30:16 +090086 RunCallbackThread thread(
87 Bind(&ExpectNotCalledOnValidSequence, Unretained(&sequence_checker)));
fdoray4bcf1082016-07-27 07:28:45 +090088}
89
Francois Doray3c2d2fd2018-02-22 21:48:38 +090090TEST(SequenceCheckerTest, CallsAllowedOnDifferentThreadsSameSequenceToken) {
fdoray4bcf1082016-07-27 07:28:45 +090091 const SequenceToken sequence_token(SequenceToken::Create());
92
93 ScopedSetSequenceTokenForCurrentThread
94 scoped_set_sequence_token_for_current_thread(sequence_token);
95 SequenceCheckerImpl sequence_checker;
fdoraye4a58272016-07-29 11:30:16 +090096 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +090097
fdoraye4a58272016-07-29 11:30:16 +090098 RunCallbackThread thread(Bind(&ExpectCalledOnValidSequenceWithSequenceToken,
99 Unretained(&sequence_checker), sequence_token));
fdoray4bcf1082016-07-27 07:28:45 +0900100}
101
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900102TEST(SequenceCheckerTest, CallsDisallowedOnSameThreadDifferentSequenceToken) {
fdoray4bcf1082016-07-27 07:28:45 +0900103 std::unique_ptr<SequenceCheckerImpl> sequence_checker;
104
105 {
106 ScopedSetSequenceTokenForCurrentThread
107 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
108 sequence_checker.reset(new SequenceCheckerImpl);
109 }
110
111 {
112 // Different SequenceToken.
113 ScopedSetSequenceTokenForCurrentThread
114 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
fdoraye4a58272016-07-29 11:30:16 +0900115 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900116 }
117
118 // No SequenceToken.
fdoraye4a58272016-07-29 11:30:16 +0900119 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900120}
121
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900122TEST(SequenceCheckerTest, DetachFromSequence) {
fdoray4bcf1082016-07-27 07:28:45 +0900123 std::unique_ptr<SequenceCheckerImpl> sequence_checker;
124
125 {
126 ScopedSetSequenceTokenForCurrentThread
127 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
128 sequence_checker.reset(new SequenceCheckerImpl);
129 }
130
131 sequence_checker->DetachFromSequence();
132
133 {
fdoraye4a58272016-07-29 11:30:16 +0900134 // Verify that CalledOnValidSequence() returns true when called with
fdoray4bcf1082016-07-27 07:28:45 +0900135 // a different sequence token after a call to DetachFromSequence().
136 ScopedSetSequenceTokenForCurrentThread
137 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
fdoraye4a58272016-07-29 11:30:16 +0900138 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900139 }
140}
141
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900142TEST(SequenceCheckerTest, DetachFromSequenceNoSequenceToken) {
fdoray4bcf1082016-07-27 07:28:45 +0900143 SequenceCheckerImpl sequence_checker;
144 sequence_checker.DetachFromSequence();
145
fdoraye4a58272016-07-29 11:30:16 +0900146 // Verify that CalledOnValidSequence() returns true when called on a
fdoray4bcf1082016-07-27 07:28:45 +0900147 // different thread after a call to DetachFromSequence().
148 RunCallbackThread thread(
fdoraye4a58272016-07-29 11:30:16 +0900149 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)));
fdoray4bcf1082016-07-27 07:28:45 +0900150
fdoraye4a58272016-07-29 11:30:16 +0900151 EXPECT_FALSE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900152}
153
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900154TEST(SequenceCheckerMacroTest, Macros) {
155 auto scope = std::make_unique<ScopedSetSequenceTokenForCurrentThread>(
156 SequenceToken::Create());
157 SEQUENCE_CHECKER(my_sequence_checker);
fdoray4bcf1082016-07-27 07:28:45 +0900158
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900159 // Don't expect a DCHECK death when a SequenceChecker is used on the right
160 // sequence.
161 DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
fdoray4bcf1082016-07-27 07:28:45 +0900162
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900163 scope.reset();
fdoray4bcf1082016-07-27 07:28:45 +0900164
gabbe9beea2017-05-11 13:15:59 +0900165#if DCHECK_IS_ON()
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900166 // Expect DCHECK death when used on a different sequence.
167 EXPECT_DCHECK_DEATH({
168 DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
169 });
gabbe9beea2017-05-11 13:15:59 +0900170#else
171 // Happily no-ops on non-dcheck builds.
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900172 DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
gabbe9beea2017-05-11 13:15:59 +0900173#endif
gabbe9beea2017-05-11 13:15:59 +0900174
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900175 DETACH_FROM_SEQUENCE(my_sequence_checker);
gabbe9beea2017-05-11 13:15:59 +0900176
Francois Doray3c2d2fd2018-02-22 21:48:38 +0900177 // Don't expect a DCHECK death when a SequenceChecker is used for the first
178 // time after having been detached.
179 DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
gabbe9beea2017-05-11 13:15:59 +0900180}
181
fdoray4bcf1082016-07-27 07:28:45 +0900182} // namespace base