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