blob: 3c21338a5b9fffaec701c180afb9fdc24f38bf64 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2013 The Chromium Authors
[email protected]285d06fc2013-08-24 15:00:332// 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
Avi Drissman63e1f992023-01-13 18:54:437#include "base/functional/bind.h"
8#include "base/functional/callback.h"
9#include "base/functional/callback_helpers.h"
Keishi Hattori0e45c022021-11-27 09:25:5210#include "base/memory/raw_ptr.h"
cfredrice22247e2021-07-22 21:08:5711#include "base/test/bind.h"
cfredrice7af0642021-07-27 21:06:5112#include "base/test/gtest_util.h"
[email protected]285d06fc2013-08-24 15:00:3313#include "testing/gtest/include/gtest/gtest.h"
14
15namespace {
16
[email protected]285d06fc2013-08-24 15:00:3317TEST(BarrierClosureTest, RunImmediatelyForZeroClosures) {
18 int count = 0;
cfredrice22247e2021-07-22 21:08:5719 base::RepeatingClosure barrier_closure = base::BarrierClosure(
Sorin Jianud01ad7f2024-10-09 03:45:4520 0, base::BindLambdaForTesting([&count] { ++count; }));
[email protected]285d06fc2013-08-24 15:00:3321 EXPECT_EQ(1, count);
cfredrice7af0642021-07-27 21:06:5122}
23
24TEST(BarrierClosureTest, ChecksIfCalledForZeroClosures) {
25 base::RepeatingClosure barrier_closure =
26 base::BarrierClosure(0, base::DoNothing());
cfredrice22247e2021-07-22 21:08:5727 EXPECT_FALSE(barrier_closure.is_null());
cfredrice7af0642021-07-27 21:06:5128
Peter Boström54119652024-11-14 00:16:3829 EXPECT_NOTREACHED_DEATH(barrier_closure.Run());
[email protected]285d06fc2013-08-24 15:00:3330}
31
32TEST(BarrierClosureTest, RunAfterNumClosures) {
33 int count = 0;
cfredrice22247e2021-07-22 21:08:5734 base::RepeatingClosure barrier_closure = base::BarrierClosure(
Sorin Jianud01ad7f2024-10-09 03:45:4535 2, base::BindLambdaForTesting([&count] { ++count; }));
[email protected]285d06fc2013-08-24 15:00:3336 EXPECT_EQ(0, count);
37
dzhioev0a3f4592015-05-07 01:05:3538 barrier_closure.Run();
[email protected]285d06fc2013-08-24 15:00:3339 EXPECT_EQ(0, count);
40
dzhioev0a3f4592015-05-07 01:05:3541 barrier_closure.Run();
[email protected]285d06fc2013-08-24 15:00:3342 EXPECT_EQ(1, count);
43}
44
dzhioev0a3f4592015-05-07 01:05:3545class DestructionIndicator {
46 public:
47 // Sets |*destructed| to true in destructor.
Peter Kasting811504a72025-01-09 03:18:5048 explicit DestructionIndicator(bool* destructed) : destructed_(destructed) {
dzhioev0a3f4592015-05-07 01:05:3549 *destructed_ = false;
50 }
51
52 ~DestructionIndicator() { *destructed_ = true; }
53
54 void DoNothing() {}
55
56 private:
Keishi Hattori0e45c022021-11-27 09:25:5257 raw_ptr<bool> destructed_;
dzhioev0a3f4592015-05-07 01:05:3558};
59
60TEST(BarrierClosureTest, ReleasesDoneClosureWhenDone) {
61 bool done_destructed = false;
kylechar01598d72019-05-21 18:35:3162 base::RepeatingClosure barrier_closure = base::BarrierClosure(
tzik0c100dc2017-06-26 06:13:1763 1,
64 base::BindOnce(&DestructionIndicator::DoNothing,
65 base::Owned(new DestructionIndicator(&done_destructed))));
dzhioev0a3f4592015-05-07 01:05:3566 EXPECT_FALSE(done_destructed);
67 barrier_closure.Run();
68 EXPECT_TRUE(done_destructed);
69}
70
dzhioev0a3f4592015-05-07 01:05:3571// Tests a case when |done_closure| resets a |barrier_closure|.
kylechar01598d72019-05-21 18:35:3172// |barrier_closure| is a RepeatingClosure holding the |done_closure|.
73// |done_closure| holds a pointer back to the |barrier_closure|. When
74// |barrier_closure| is Run() it calls ResetBarrierClosure() which erases the
75// |barrier_closure| while still inside of its Run(). The Run() implementation
76// (in base::BarrierClosure) must not try use itself after executing
77// ResetBarrierClosure() or this test would crash inside Run().
dzhioev0a3f4592015-05-07 01:05:3578TEST(BarrierClosureTest, KeepingClosureAliveUntilDone) {
kylechar01598d72019-05-21 18:35:3179 base::RepeatingClosure barrier_closure;
cfredrice22247e2021-07-22 21:08:5780 barrier_closure =
Sorin Jianud01ad7f2024-10-09 03:45:4581 base::BarrierClosure(1, base::BindLambdaForTesting([&barrier_closure] {
cfredrice22247e2021-07-22 21:08:5782 barrier_closure = base::RepeatingClosure();
83 }));
dzhioev0a3f4592015-05-07 01:05:3584 barrier_closure.Run();
cfredrice22247e2021-07-22 21:08:5785 EXPECT_TRUE(barrier_closure.is_null());
dzhioev0a3f4592015-05-07 01:05:3586}
87
[email protected]285d06fc2013-08-24 15:00:3388} // namespace