xref: /aosp_15_r20/external/cronet/base/barrier_closure_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/barrier_closure.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker namespace {
16*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierClosureTest,RunImmediatelyForZeroClosures)17*6777b538SAndroid Build Coastguard Worker TEST(BarrierClosureTest, RunImmediatelyForZeroClosures) {
18*6777b538SAndroid Build Coastguard Worker   int count = 0;
19*6777b538SAndroid Build Coastguard Worker   base::RepeatingClosure barrier_closure = base::BarrierClosure(
20*6777b538SAndroid Build Coastguard Worker       0, base::BindLambdaForTesting([&count]() { ++count; }));
21*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, count);
22*6777b538SAndroid Build Coastguard Worker }
23*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierClosureTest,ChecksIfCalledForZeroClosures)24*6777b538SAndroid Build Coastguard Worker TEST(BarrierClosureTest, ChecksIfCalledForZeroClosures) {
25*6777b538SAndroid Build Coastguard Worker   base::RepeatingClosure barrier_closure =
26*6777b538SAndroid Build Coastguard Worker       base::BarrierClosure(0, base::DoNothing());
27*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(barrier_closure.is_null());
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker   EXPECT_CHECK_DEATH(barrier_closure.Run());
30*6777b538SAndroid Build Coastguard Worker }
31*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierClosureTest,RunAfterNumClosures)32*6777b538SAndroid Build Coastguard Worker TEST(BarrierClosureTest, RunAfterNumClosures) {
33*6777b538SAndroid Build Coastguard Worker   int count = 0;
34*6777b538SAndroid Build Coastguard Worker   base::RepeatingClosure barrier_closure = base::BarrierClosure(
35*6777b538SAndroid Build Coastguard Worker       2, base::BindLambdaForTesting([&count]() { ++count; }));
36*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, count);
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker   barrier_closure.Run();
39*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, count);
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker   barrier_closure.Run();
42*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, count);
43*6777b538SAndroid Build Coastguard Worker }
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker class DestructionIndicator {
46*6777b538SAndroid Build Coastguard Worker  public:
47*6777b538SAndroid Build Coastguard Worker   // Sets |*destructed| to true in destructor.
DestructionIndicator(bool * destructed)48*6777b538SAndroid Build Coastguard Worker   DestructionIndicator(bool* destructed) : destructed_(destructed) {
49*6777b538SAndroid Build Coastguard Worker     *destructed_ = false;
50*6777b538SAndroid Build Coastguard Worker   }
51*6777b538SAndroid Build Coastguard Worker 
~DestructionIndicator()52*6777b538SAndroid Build Coastguard Worker   ~DestructionIndicator() { *destructed_ = true; }
53*6777b538SAndroid Build Coastguard Worker 
DoNothing()54*6777b538SAndroid Build Coastguard Worker   void DoNothing() {}
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker  private:
57*6777b538SAndroid Build Coastguard Worker   raw_ptr<bool> destructed_;
58*6777b538SAndroid Build Coastguard Worker };
59*6777b538SAndroid Build Coastguard Worker 
TEST(BarrierClosureTest,ReleasesDoneClosureWhenDone)60*6777b538SAndroid Build Coastguard Worker TEST(BarrierClosureTest, ReleasesDoneClosureWhenDone) {
61*6777b538SAndroid Build Coastguard Worker   bool done_destructed = false;
62*6777b538SAndroid Build Coastguard Worker   base::RepeatingClosure barrier_closure = base::BarrierClosure(
63*6777b538SAndroid Build Coastguard Worker       1,
64*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&DestructionIndicator::DoNothing,
65*6777b538SAndroid Build Coastguard Worker                      base::Owned(new DestructionIndicator(&done_destructed))));
66*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(done_destructed);
67*6777b538SAndroid Build Coastguard Worker   barrier_closure.Run();
68*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(done_destructed);
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker // Tests a case when |done_closure| resets a |barrier_closure|.
72*6777b538SAndroid Build Coastguard Worker // |barrier_closure| is a RepeatingClosure holding the |done_closure|.
73*6777b538SAndroid Build Coastguard Worker // |done_closure| holds a pointer back to the |barrier_closure|. When
74*6777b538SAndroid Build Coastguard Worker // |barrier_closure| is Run() it calls ResetBarrierClosure() which erases the
75*6777b538SAndroid Build Coastguard Worker // |barrier_closure| while still inside of its Run(). The Run() implementation
76*6777b538SAndroid Build Coastguard Worker // (in base::BarrierClosure) must not try use itself after executing
77*6777b538SAndroid Build Coastguard Worker // ResetBarrierClosure() or this test would crash inside Run().
TEST(BarrierClosureTest,KeepingClosureAliveUntilDone)78*6777b538SAndroid Build Coastguard Worker TEST(BarrierClosureTest, KeepingClosureAliveUntilDone) {
79*6777b538SAndroid Build Coastguard Worker   base::RepeatingClosure barrier_closure;
80*6777b538SAndroid Build Coastguard Worker   barrier_closure =
81*6777b538SAndroid Build Coastguard Worker       base::BarrierClosure(1, base::BindLambdaForTesting([&barrier_closure]() {
82*6777b538SAndroid Build Coastguard Worker                              barrier_closure = base::RepeatingClosure();
83*6777b538SAndroid Build Coastguard Worker                            }));
84*6777b538SAndroid Build Coastguard Worker   barrier_closure.Run();
85*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(barrier_closure.is_null());
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker }  // namespace
89