blob: 7bb728550a3ba5c76a65e44319dd09bc7c79f30e [file] [log] [blame]
[email protected]285d06fc2013-08-24 15:00:331// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/barrier_closure.h"
6
7#include "base/bind.h"
cfredrice22247e2021-07-22 21:08:578#include "base/test/bind.h"
[email protected]285d06fc2013-08-24 15:00:339#include "testing/gtest/include/gtest/gtest.h"
10
11namespace {
12
[email protected]285d06fc2013-08-24 15:00:3313TEST(BarrierClosureTest, RunImmediatelyForZeroClosures) {
14 int count = 0;
cfredrice22247e2021-07-22 21:08:5715 base::RepeatingClosure barrier_closure = base::BarrierClosure(
16 0, base::BindLambdaForTesting([&count]() { ++count; }));
[email protected]285d06fc2013-08-24 15:00:3317 EXPECT_EQ(1, count);
cfredrice22247e2021-07-22 21:08:5718 EXPECT_FALSE(barrier_closure.is_null());
[email protected]285d06fc2013-08-24 15:00:3319}
20
21TEST(BarrierClosureTest, RunAfterNumClosures) {
22 int count = 0;
cfredrice22247e2021-07-22 21:08:5723 base::RepeatingClosure barrier_closure = base::BarrierClosure(
24 2, base::BindLambdaForTesting([&count]() { ++count; }));
[email protected]285d06fc2013-08-24 15:00:3325 EXPECT_EQ(0, count);
26
dzhioev0a3f4592015-05-07 01:05:3527 barrier_closure.Run();
[email protected]285d06fc2013-08-24 15:00:3328 EXPECT_EQ(0, count);
29
dzhioev0a3f4592015-05-07 01:05:3530 barrier_closure.Run();
[email protected]285d06fc2013-08-24 15:00:3331 EXPECT_EQ(1, count);
32}
33
dzhioev0a3f4592015-05-07 01:05:3534class DestructionIndicator {
35 public:
36 // Sets |*destructed| to true in destructor.
37 DestructionIndicator(bool* destructed) : destructed_(destructed) {
38 *destructed_ = false;
39 }
40
41 ~DestructionIndicator() { *destructed_ = true; }
42
43 void DoNothing() {}
44
45 private:
46 bool* destructed_;
47};
48
49TEST(BarrierClosureTest, ReleasesDoneClosureWhenDone) {
50 bool done_destructed = false;
kylechar01598d72019-05-21 18:35:3151 base::RepeatingClosure barrier_closure = base::BarrierClosure(
tzik0c100dc2017-06-26 06:13:1752 1,
53 base::BindOnce(&DestructionIndicator::DoNothing,
54 base::Owned(new DestructionIndicator(&done_destructed))));
dzhioev0a3f4592015-05-07 01:05:3555 EXPECT_FALSE(done_destructed);
56 barrier_closure.Run();
57 EXPECT_TRUE(done_destructed);
58}
59
dzhioev0a3f4592015-05-07 01:05:3560// Tests a case when |done_closure| resets a |barrier_closure|.
kylechar01598d72019-05-21 18:35:3161// |barrier_closure| is a RepeatingClosure holding the |done_closure|.
62// |done_closure| holds a pointer back to the |barrier_closure|. When
63// |barrier_closure| is Run() it calls ResetBarrierClosure() which erases the
64// |barrier_closure| while still inside of its Run(). The Run() implementation
65// (in base::BarrierClosure) must not try use itself after executing
66// ResetBarrierClosure() or this test would crash inside Run().
dzhioev0a3f4592015-05-07 01:05:3567TEST(BarrierClosureTest, KeepingClosureAliveUntilDone) {
kylechar01598d72019-05-21 18:35:3168 base::RepeatingClosure barrier_closure;
cfredrice22247e2021-07-22 21:08:5769 barrier_closure =
70 base::BarrierClosure(1, base::BindLambdaForTesting([&barrier_closure]() {
71 barrier_closure = base::RepeatingClosure();
72 }));
dzhioev0a3f4592015-05-07 01:05:3573 barrier_closure.Run();
cfredrice22247e2021-07-22 21:08:5774 EXPECT_TRUE(barrier_closure.is_null());
dzhioev0a3f4592015-05-07 01:05:3575}
76
[email protected]285d06fc2013-08-24 15:00:3377} // namespace