1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 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/threading/thread_checker.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/sequence_token.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/test/test_simple_task_runner.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/threading/simple_thread.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_local.h"
19*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker namespace base::internal {
22*6777b538SAndroid Build Coastguard Worker namespace {
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard Worker // A thread that runs a callback.
25*6777b538SAndroid Build Coastguard Worker class RunCallbackThread : public SimpleThread {
26*6777b538SAndroid Build Coastguard Worker public:
RunCallbackThread(OnceClosure callback)27*6777b538SAndroid Build Coastguard Worker explicit RunCallbackThread(OnceClosure callback)
28*6777b538SAndroid Build Coastguard Worker : SimpleThread("RunCallbackThread"), callback_(std::move(callback)) {}
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker RunCallbackThread(const RunCallbackThread&) = delete;
31*6777b538SAndroid Build Coastguard Worker RunCallbackThread& operator=(const RunCallbackThread&) = delete;
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker private:
34*6777b538SAndroid Build Coastguard Worker // SimpleThread:
Run()35*6777b538SAndroid Build Coastguard Worker void Run() override { std::move(callback_).Run(); }
36*6777b538SAndroid Build Coastguard Worker
37*6777b538SAndroid Build Coastguard Worker OnceClosure callback_;
38*6777b538SAndroid Build Coastguard Worker };
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker // Runs a callback on a new thread synchronously.
RunCallbackOnNewThreadSynchronously(OnceClosure callback)41*6777b538SAndroid Build Coastguard Worker void RunCallbackOnNewThreadSynchronously(OnceClosure callback) {
42*6777b538SAndroid Build Coastguard Worker RunCallbackThread run_callback_thread(std::move(callback));
43*6777b538SAndroid Build Coastguard Worker run_callback_thread.Start();
44*6777b538SAndroid Build Coastguard Worker run_callback_thread.Join();
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker
ExpectCalledOnValidThread(ThreadCheckerImpl * thread_checker)47*6777b538SAndroid Build Coastguard Worker void ExpectCalledOnValidThread(ThreadCheckerImpl* thread_checker) {
48*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(thread_checker);
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard Worker // This should bind |thread_checker| to the current thread if it wasn't
51*6777b538SAndroid Build Coastguard Worker // already bound to a thread.
52*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(thread_checker->CalledOnValidThread());
53*6777b538SAndroid Build Coastguard Worker
54*6777b538SAndroid Build Coastguard Worker // Since |thread_checker| is now bound to the current thread, another call to
55*6777b538SAndroid Build Coastguard Worker // CalledOnValidThread() should return true.
56*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(thread_checker->CalledOnValidThread());
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker
ExpectNotCalledOnValidThread(ThreadCheckerImpl * thread_checker)59*6777b538SAndroid Build Coastguard Worker void ExpectNotCalledOnValidThread(ThreadCheckerImpl* thread_checker) {
60*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(thread_checker);
61*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(thread_checker->CalledOnValidThread());
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker
ExpectNotCalledOnValidThreadWithSequenceTokenThreadBound(ThreadCheckerImpl * thread_checker,SequenceToken sequence_token)64*6777b538SAndroid Build Coastguard Worker void ExpectNotCalledOnValidThreadWithSequenceTokenThreadBound(
65*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl* thread_checker,
66*6777b538SAndroid Build Coastguard Worker SequenceToken sequence_token) {
67*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(sequence_token, /* is_thread_bound=*/true);
68*6777b538SAndroid Build Coastguard Worker ExpectNotCalledOnValidThread(thread_checker);
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker } // namespace
72*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,AllowedSameThreadNoSequenceToken)73*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, AllowedSameThreadNoSequenceToken) {
74*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl thread_checker;
75*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(thread_checker.CalledOnValidThread());
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,AllowedSameThreadAndSequenceDifferentThreadBoundTasks)78*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, AllowedSameThreadAndSequenceDifferentThreadBoundTasks) {
79*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ThreadCheckerImpl> thread_checker;
80*6777b538SAndroid Build Coastguard Worker const SequenceToken sequence_token = SequenceToken::Create();
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker {
83*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(sequence_token,
84*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/true);
85*6777b538SAndroid Build Coastguard Worker thread_checker = std::make_unique<ThreadCheckerImpl>();
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker
88*6777b538SAndroid Build Coastguard Worker {
89*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(sequence_token,
90*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/true);
91*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(thread_checker->CalledOnValidThread());
92*6777b538SAndroid Build Coastguard Worker }
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,AllowedSameThreadSequenceAndTaskNotThreadBound)95*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, AllowedSameThreadSequenceAndTaskNotThreadBound) {
96*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
97*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
98*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl thread_checker;
99*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(thread_checker.CalledOnValidThread());
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,DisallowedSameThreadAndSequenceDifferentTasksNotThreadBound)102*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest,
103*6777b538SAndroid Build Coastguard Worker DisallowedSameThreadAndSequenceDifferentTasksNotThreadBound) {
104*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ThreadCheckerImpl> thread_checker;
105*6777b538SAndroid Build Coastguard Worker
106*6777b538SAndroid Build Coastguard Worker {
107*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
108*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
109*6777b538SAndroid Build Coastguard Worker thread_checker = std::make_unique<ThreadCheckerImpl>();
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker {
113*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
114*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
115*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(thread_checker->CalledOnValidThread());
116*6777b538SAndroid Build Coastguard Worker }
117*6777b538SAndroid Build Coastguard Worker }
118*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,DisallowedDifferentThreadsNoSequenceToken)119*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DisallowedDifferentThreadsNoSequenceToken) {
120*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl thread_checker;
121*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
122*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidThread, Unretained(&thread_checker)));
123*6777b538SAndroid Build Coastguard Worker }
124*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,DisallowedDifferentThreadsSameSequence)125*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DisallowedDifferentThreadsSameSequence) {
126*6777b538SAndroid Build Coastguard Worker SingleThreadTaskRunner::CurrentDefaultHandle
127*6777b538SAndroid Build Coastguard Worker single_thread_task_runner_current_default_handle(
128*6777b538SAndroid Build Coastguard Worker MakeRefCounted<TestSimpleTaskRunner>());
129*6777b538SAndroid Build Coastguard Worker const SequenceToken sequence_token(SequenceToken::Create());
130*6777b538SAndroid Build Coastguard Worker
131*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(sequence_token,
132*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
133*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl thread_checker;
134*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(thread_checker.CalledOnValidThread());
135*6777b538SAndroid Build Coastguard Worker
136*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
137*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidThreadWithSequenceTokenThreadBound,
138*6777b538SAndroid Build Coastguard Worker Unretained(&thread_checker), sequence_token));
139*6777b538SAndroid Build Coastguard Worker }
140*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,DisallowedSameThreadDifferentSequence)141*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DisallowedSameThreadDifferentSequence) {
142*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ThreadCheckerImpl> thread_checker;
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker SingleThreadTaskRunner::CurrentDefaultHandle
145*6777b538SAndroid Build Coastguard Worker single_thread_task_runner_current_default_handle(
146*6777b538SAndroid Build Coastguard Worker MakeRefCounted<TestSimpleTaskRunner>());
147*6777b538SAndroid Build Coastguard Worker
148*6777b538SAndroid Build Coastguard Worker {
149*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
150*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
151*6777b538SAndroid Build Coastguard Worker thread_checker = std::make_unique<ThreadCheckerImpl>();
152*6777b538SAndroid Build Coastguard Worker }
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard Worker {
155*6777b538SAndroid Build Coastguard Worker // Different SequenceToken.
156*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
157*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
158*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(thread_checker->CalledOnValidThread());
159*6777b538SAndroid Build Coastguard Worker }
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker // No SequenceToken.
162*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(thread_checker->CalledOnValidThread());
163*6777b538SAndroid Build Coastguard Worker }
164*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,DetachFromThread)165*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DetachFromThread) {
166*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl thread_checker;
167*6777b538SAndroid Build Coastguard Worker thread_checker.DetachFromThread();
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker // Verify that CalledOnValidThread() returns true when called on a different
170*6777b538SAndroid Build Coastguard Worker // thread after a call to DetachFromThread().
171*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
172*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidThread, Unretained(&thread_checker)));
173*6777b538SAndroid Build Coastguard Worker
174*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(thread_checker.CalledOnValidThread());
175*6777b538SAndroid Build Coastguard Worker }
176*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,DetachFromThreadWithSequenceToken)177*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DetachFromThreadWithSequenceToken) {
178*6777b538SAndroid Build Coastguard Worker SingleThreadTaskRunner::CurrentDefaultHandle
179*6777b538SAndroid Build Coastguard Worker single_thread_task_runner_current_default_handle(
180*6777b538SAndroid Build Coastguard Worker MakeRefCounted<TestSimpleTaskRunner>());
181*6777b538SAndroid Build Coastguard Worker TaskScope task_scope(SequenceToken::Create(),
182*6777b538SAndroid Build Coastguard Worker /* is_thread_bound=*/false);
183*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl thread_checker;
184*6777b538SAndroid Build Coastguard Worker thread_checker.DetachFromThread();
185*6777b538SAndroid Build Coastguard Worker
186*6777b538SAndroid Build Coastguard Worker // Verify that CalledOnValidThread() returns true when called on a different
187*6777b538SAndroid Build Coastguard Worker // thread after a call to DetachFromThread().
188*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
189*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidThread, Unretained(&thread_checker)));
190*6777b538SAndroid Build Coastguard Worker
191*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(thread_checker.CalledOnValidThread());
192*6777b538SAndroid Build Coastguard Worker }
193*6777b538SAndroid Build Coastguard Worker
194*6777b538SAndroid Build Coastguard Worker // Owns a ThreadCheckerImpl and asserts that CalledOnValidThread() is valid
195*6777b538SAndroid Build Coastguard Worker // in ~ThreadCheckerOwner.
196*6777b538SAndroid Build Coastguard Worker class ThreadCheckerOwner {
197*6777b538SAndroid Build Coastguard Worker public:
ThreadCheckerOwner(bool detach_from_thread)198*6777b538SAndroid Build Coastguard Worker explicit ThreadCheckerOwner(bool detach_from_thread) {
199*6777b538SAndroid Build Coastguard Worker if (detach_from_thread)
200*6777b538SAndroid Build Coastguard Worker checker_.DetachFromThread();
201*6777b538SAndroid Build Coastguard Worker }
202*6777b538SAndroid Build Coastguard Worker
203*6777b538SAndroid Build Coastguard Worker ThreadCheckerOwner(const ThreadCheckerOwner&) = delete;
204*6777b538SAndroid Build Coastguard Worker ThreadCheckerOwner& operator=(const ThreadCheckerOwner&) = delete;
205*6777b538SAndroid Build Coastguard Worker
~ThreadCheckerOwner()206*6777b538SAndroid Build Coastguard Worker ~ThreadCheckerOwner() { EXPECT_TRUE(checker_.CalledOnValidThread()); }
207*6777b538SAndroid Build Coastguard Worker
208*6777b538SAndroid Build Coastguard Worker private:
209*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl checker_;
210*6777b538SAndroid Build Coastguard Worker };
211*6777b538SAndroid Build Coastguard Worker
212*6777b538SAndroid Build Coastguard Worker // Verifies ThreadCheckerImpl::CalledOnValidThread() returns true if called
213*6777b538SAndroid Build Coastguard Worker // during thread destruction.
TEST(ThreadCheckerTest,CalledOnValidThreadFromThreadDestruction)214*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, CalledOnValidThreadFromThreadDestruction) {
215*6777b538SAndroid Build Coastguard Worker ThreadLocalOwnedPointer<ThreadCheckerOwner> thread_local_owner;
216*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(BindLambdaForTesting([&]() {
217*6777b538SAndroid Build Coastguard Worker thread_local_owner.Set(std::make_unique<ThreadCheckerOwner>(false));
218*6777b538SAndroid Build Coastguard Worker }));
219*6777b538SAndroid Build Coastguard Worker }
220*6777b538SAndroid Build Coastguard Worker
221*6777b538SAndroid Build Coastguard Worker // Variant of CalledOnValidThreadFromThreadDestruction that calls
222*6777b538SAndroid Build Coastguard Worker // ThreadCheckerImpl::DetachFromThread().
TEST(ThreadCheckerTest,CalledOnValidThreadFromThreadDestructionDetached)223*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, CalledOnValidThreadFromThreadDestructionDetached) {
224*6777b538SAndroid Build Coastguard Worker ThreadLocalOwnedPointer<ThreadCheckerOwner> thread_local_owner;
225*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(BindLambdaForTesting([&]() {
226*6777b538SAndroid Build Coastguard Worker thread_local_owner.Set(std::make_unique<ThreadCheckerOwner>(true));
227*6777b538SAndroid Build Coastguard Worker }));
228*6777b538SAndroid Build Coastguard Worker }
229*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,Move)230*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, Move) {
231*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl initial;
232*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(initial.CalledOnValidThread());
233*6777b538SAndroid Build Coastguard Worker
234*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl move_constructed(std::move(initial));
235*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(move_constructed.CalledOnValidThread());
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl move_assigned;
238*6777b538SAndroid Build Coastguard Worker move_assigned = std::move(move_constructed);
239*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(move_assigned.CalledOnValidThread());
240*6777b538SAndroid Build Coastguard Worker
241*6777b538SAndroid Build Coastguard Worker // The two ThreadCheckerImpls moved from should be able to rebind to another
242*6777b538SAndroid Build Coastguard Worker // thread.
243*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
244*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));
245*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
246*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidThread, Unretained(&move_constructed)));
247*6777b538SAndroid Build Coastguard Worker
248*6777b538SAndroid Build Coastguard Worker // But the latest one shouldn't be able to run on another thread.
249*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
250*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidThread, Unretained(&move_assigned)));
251*6777b538SAndroid Build Coastguard Worker
252*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(move_assigned.CalledOnValidThread());
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,MoveAssignIntoDetached)255*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, MoveAssignIntoDetached) {
256*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl initial;
257*6777b538SAndroid Build Coastguard Worker
258*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl move_assigned;
259*6777b538SAndroid Build Coastguard Worker move_assigned.DetachFromThread();
260*6777b538SAndroid Build Coastguard Worker move_assigned = std::move(initial);
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Worker // |initial| is detached after move.
263*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
264*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));
265*6777b538SAndroid Build Coastguard Worker
266*6777b538SAndroid Build Coastguard Worker // |move_assigned| should be associated with the main thread.
267*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
268*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidThread, Unretained(&move_assigned)));
269*6777b538SAndroid Build Coastguard Worker
270*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(move_assigned.CalledOnValidThread());
271*6777b538SAndroid Build Coastguard Worker }
272*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,MoveFromDetachedRebinds)273*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, MoveFromDetachedRebinds) {
274*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl initial;
275*6777b538SAndroid Build Coastguard Worker initial.DetachFromThread();
276*6777b538SAndroid Build Coastguard Worker
277*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl moved_into(std::move(initial));
278*6777b538SAndroid Build Coastguard Worker
279*6777b538SAndroid Build Coastguard Worker // |initial| is still detached after move.
280*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
281*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));
282*6777b538SAndroid Build Coastguard Worker
283*6777b538SAndroid Build Coastguard Worker // |moved_into| is bound to the current thread as part of the move.
284*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
285*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectNotCalledOnValidThread, Unretained(&moved_into)));
286*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(moved_into.CalledOnValidThread());
287*6777b538SAndroid Build Coastguard Worker }
288*6777b538SAndroid Build Coastguard Worker
TEST(ThreadCheckerTest,MoveOffThreadBanned)289*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, MoveOffThreadBanned) {
290*6777b538SAndroid Build Coastguard Worker GTEST_FLAG_SET(death_test_style, "threadsafe");
291*6777b538SAndroid Build Coastguard Worker
292*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl other_thread;
293*6777b538SAndroid Build Coastguard Worker other_thread.DetachFromThread();
294*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
295*6777b538SAndroid Build Coastguard Worker BindOnce(&ExpectCalledOnValidThread, Unretained(&other_thread)));
296*6777b538SAndroid Build Coastguard Worker
297*6777b538SAndroid Build Coastguard Worker EXPECT_DCHECK_DEATH(ThreadCheckerImpl main_thread(std::move(other_thread)));
298*6777b538SAndroid Build Coastguard Worker }
299*6777b538SAndroid Build Coastguard Worker
300*6777b538SAndroid Build Coastguard Worker namespace {
301*6777b538SAndroid Build Coastguard Worker
302*6777b538SAndroid Build Coastguard Worker // This fixture is a helper for unit testing the thread checker macros as it is
303*6777b538SAndroid Build Coastguard Worker // not possible to inline ExpectDeathOnOtherThread() and
304*6777b538SAndroid Build Coastguard Worker // ExpectNoDeathOnOtherThreadAfterDetach() as lambdas since binding
305*6777b538SAndroid Build Coastguard Worker // |Unretained(&my_sequence_checker)| wouldn't compile on non-dcheck builds
306*6777b538SAndroid Build Coastguard Worker // where it won't be defined.
307*6777b538SAndroid Build Coastguard Worker class ThreadCheckerMacroTest : public testing::Test {
308*6777b538SAndroid Build Coastguard Worker public:
309*6777b538SAndroid Build Coastguard Worker ThreadCheckerMacroTest() = default;
310*6777b538SAndroid Build Coastguard Worker
311*6777b538SAndroid Build Coastguard Worker ThreadCheckerMacroTest(const ThreadCheckerMacroTest&) = delete;
312*6777b538SAndroid Build Coastguard Worker ThreadCheckerMacroTest& operator=(const ThreadCheckerMacroTest&) = delete;
313*6777b538SAndroid Build Coastguard Worker
ExpectDeathOnOtherThread()314*6777b538SAndroid Build Coastguard Worker void ExpectDeathOnOtherThread() {
315*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
316*6777b538SAndroid Build Coastguard Worker EXPECT_DCHECK_DEATH({ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); });
317*6777b538SAndroid Build Coastguard Worker #else
318*6777b538SAndroid Build Coastguard Worker // Happily no-ops on non-dcheck builds.
319*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
320*6777b538SAndroid Build Coastguard Worker #endif
321*6777b538SAndroid Build Coastguard Worker }
322*6777b538SAndroid Build Coastguard Worker
ExpectNoDeathOnOtherThreadAfterDetach()323*6777b538SAndroid Build Coastguard Worker void ExpectNoDeathOnOtherThreadAfterDetach() {
324*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
325*6777b538SAndroid Build Coastguard Worker }
326*6777b538SAndroid Build Coastguard Worker
327*6777b538SAndroid Build Coastguard Worker protected:
328*6777b538SAndroid Build Coastguard Worker THREAD_CHECKER(thread_checker_);
329*6777b538SAndroid Build Coastguard Worker };
330*6777b538SAndroid Build Coastguard Worker
331*6777b538SAndroid Build Coastguard Worker } // namespace
332*6777b538SAndroid Build Coastguard Worker
TEST_F(ThreadCheckerMacroTest,Macros)333*6777b538SAndroid Build Coastguard Worker TEST_F(ThreadCheckerMacroTest, Macros) {
334*6777b538SAndroid Build Coastguard Worker GTEST_FLAG_SET(death_test_style, "threadsafe");
335*6777b538SAndroid Build Coastguard Worker
336*6777b538SAndroid Build Coastguard Worker THREAD_CHECKER(my_thread_checker);
337*6777b538SAndroid Build Coastguard Worker
338*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(BindOnce(
339*6777b538SAndroid Build Coastguard Worker &ThreadCheckerMacroTest::ExpectDeathOnOtherThread, Unretained(this)));
340*6777b538SAndroid Build Coastguard Worker
341*6777b538SAndroid Build Coastguard Worker DETACH_FROM_THREAD(thread_checker_);
342*6777b538SAndroid Build Coastguard Worker
343*6777b538SAndroid Build Coastguard Worker RunCallbackOnNewThreadSynchronously(
344*6777b538SAndroid Build Coastguard Worker BindOnce(&ThreadCheckerMacroTest::ExpectNoDeathOnOtherThreadAfterDetach,
345*6777b538SAndroid Build Coastguard Worker Unretained(this)));
346*6777b538SAndroid Build Coastguard Worker }
347*6777b538SAndroid Build Coastguard Worker
348*6777b538SAndroid Build Coastguard Worker } // namespace base::internal
349