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