blob: 937d645869355e831b57368da94faf3d2ace702d [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"
cfredrice7af0642021-07-27 21:06:518#include "base/callback_helpers.h"
cfredrice22247e2021-07-22 21:08:579#include "base/test/bind.h"
cfredrice7af0642021-07-27 21:06:5110#include "base/test/gtest_util.h"
[email protected]285d06fc2013-08-24 15:00:3311#include "testing/gtest/include/gtest/gtest.h"
12
13namespace {
14
[email protected]285d06fc2013-08-24 15:00:3315TEST(BarrierClosureTest, RunImmediatelyForZeroClosures) {
16 int count = 0;
cfredrice22247e2021-07-22 21:08:5717 base::RepeatingClosure barrier_closure = base::BarrierClosure(
18 0, base::BindLambdaForTesting([&count]() { ++count; }));
[email protected]285d06fc2013-08-24 15:00:3319 EXPECT_EQ(1, count);
cfredrice7af0642021-07-27 21:06:5120}
21
22TEST(BarrierClosureTest, ChecksIfCalledForZeroClosures) {
23 base::RepeatingClosure barrier_closure =
24 base::BarrierClosure(0, base::DoNothing());
cfredrice22247e2021-07-22 21:08:5725 EXPECT_FALSE(barrier_closure.is_null());
cfredrice7af0642021-07-27 21:06:5126
27 EXPECT_CHECK_DEATH(barrier_closure.Run());
[email protected]285d06fc2013-08-24 15:00:3328}
29
30TEST(BarrierClosureTest, RunAfterNumClosures) {
31 int count = 0;
cfredrice22247e2021-07-22 21:08:5732 base::RepeatingClosure barrier_closure = base::BarrierClosure(
33 2, base::BindLambdaForTesting([&count]() { ++count; }));
[email protected]285d06fc2013-08-24 15:00:3334 EXPECT_EQ(0, count);
35
dzhioev0a3f4592015-05-07 01:05:3536 barrier_closure.Run();
[email protected]285d06fc2013-08-24 15:00:3337 EXPECT_EQ(0, count);
38
dzhioev0a3f4592015-05-07 01:05:3539 barrier_closure.Run();
[email protected]285d06fc2013-08-24 15:00:3340 EXPECT_EQ(1, count);
41}
42
dzhioev0a3f4592015-05-07 01:05:3543class DestructionIndicator {
44 public:
45 // Sets |*destructed| to true in destructor.
46 DestructionIndicator(bool* destructed) : destructed_(destructed) {
47 *destructed_ = false;
48 }
49
50 ~DestructionIndicator() { *destructed_ = true; }
51
52 void DoNothing() {}
53
54 private:
55 bool* destructed_;
56};
57
58TEST(BarrierClosureTest, ReleasesDoneClosureWhenDone) {
59 bool done_destructed = false;
kylechar01598d72019-05-21 18:35:3160 base::RepeatingClosure barrier_closure = base::BarrierClosure(
tzik0c100dc2017-06-26 06:13:1761 1,
62 base::BindOnce(&DestructionIndicator::DoNothing,
63 base::Owned(new DestructionIndicator(&done_destructed))));
dzhioev0a3f4592015-05-07 01:05:3564 EXPECT_FALSE(done_destructed);
65 barrier_closure.Run();
66 EXPECT_TRUE(done_destructed);
67}
68
dzhioev0a3f4592015-05-07 01:05:3569// Tests a case when |done_closure| resets a |barrier_closure|.
kylechar01598d72019-05-21 18:35:3170// |barrier_closure| is a RepeatingClosure holding the |done_closure|.
71// |done_closure| holds a pointer back to the |barrier_closure|. When
72// |barrier_closure| is Run() it calls ResetBarrierClosure() which erases the
73// |barrier_closure| while still inside of its Run(). The Run() implementation
74// (in base::BarrierClosure) must not try use itself after executing
75// ResetBarrierClosure() or this test would crash inside Run().
dzhioev0a3f4592015-05-07 01:05:3576TEST(BarrierClosureTest, KeepingClosureAliveUntilDone) {
kylechar01598d72019-05-21 18:35:3177 base::RepeatingClosure barrier_closure;
cfredrice22247e2021-07-22 21:08:5778 barrier_closure =
79 base::BarrierClosure(1, base::BindLambdaForTesting([&barrier_closure]() {
80 barrier_closure = base::RepeatingClosure();
81 }));
dzhioev0a3f4592015-05-07 01:05:3582 barrier_closure.Run();
cfredrice22247e2021-07-22 21:08:5783 EXPECT_TRUE(barrier_closure.is_null());
dzhioev0a3f4592015-05-07 01:05:3584}
85
[email protected]285d06fc2013-08-24 15:00:3386} // namespace