blob: 613b46cd473b4bd3fd470f64dc85c749b0bf8691 [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
tzik34bf6052017-04-27 14:03:217#include <utility>
8
[email protected]285d06fc2013-08-24 15:00:339#include "base/atomic_ref_count.h"
Avi Drissman63e1f992023-01-13 18:54:4310#include "base/functional/bind.h"
tzik34bf6052017-04-27 14:03:2111#include "base/memory/ptr_util.h"
Peter Kasting9f9d8e32021-08-12 01:14:5412#include "base/numerics/safe_conversions.h"
[email protected]285d06fc2013-08-24 15:00:3313
tzik34bf6052017-04-27 14:03:2114namespace base {
[email protected]285d06fc2013-08-24 15:00:3315namespace {
16
17// Maintains state for a BarrierClosure.
18class BarrierInfo {
19 public:
Peter Kasting9f9d8e32021-08-12 01:14:5420 BarrierInfo(size_t num_callbacks_left, OnceClosure done_closure);
Victor Hugo Vianna Silvaa8951a7a2022-12-15 15:22:4421 BarrierInfo(const BarrierInfo&) = delete;
22 BarrierInfo& operator=(const BarrierInfo&) = delete;
[email protected]285d06fc2013-08-24 15:00:3323 void Run();
24
25 private:
tzik34bf6052017-04-27 14:03:2126 AtomicRefCount num_callbacks_left_;
27 OnceClosure done_closure_;
[email protected]285d06fc2013-08-24 15:00:3328};
29
Peter Kasting9f9d8e32021-08-12 01:14:5430BarrierInfo::BarrierInfo(size_t num_callbacks, OnceClosure done_closure)
31 : num_callbacks_left_(checked_cast<int>(num_callbacks)),
tzik34bf6052017-04-27 14:03:2132 done_closure_(std::move(done_closure)) {}
[email protected]285d06fc2013-08-24 15:00:3333
34void BarrierInfo::Run() {
Jeremy Romanee96d562017-07-06 19:09:3635 DCHECK(!num_callbacks_left_.IsZero());
36 if (!num_callbacks_left_.Decrement())
tzik34bf6052017-04-27 14:03:2137 std::move(done_closure_).Run();
[email protected]285d06fc2013-08-24 15:00:3338}
39
cfredrice7af0642021-07-27 21:06:5140void ShouldNeverRun() {
41 CHECK(false);
42}
43
[email protected]285d06fc2013-08-24 15:00:3344} // namespace
45
Peter Kasting9f9d8e32021-08-12 01:14:5446RepeatingClosure BarrierClosure(size_t num_callbacks_left,
tzik34bf6052017-04-27 14:03:2147 OnceClosure done_closure) {
cfredrice7af0642021-07-27 21:06:5148 if (num_callbacks_left == 0) {
tzik34bf6052017-04-27 14:03:2149 std::move(done_closure).Run();
cfredrice7af0642021-07-27 21:06:5150 return BindRepeating(&ShouldNeverRun);
51 }
[email protected]285d06fc2013-08-24 15:00:3352
cfredrice7af0642021-07-27 21:06:5153 return BindRepeating(&BarrierInfo::Run,
54 std::make_unique<BarrierInfo>(num_callbacks_left,
55 std::move(done_closure)));
[email protected]285d06fc2013-08-24 15:00:3356}
57
[email protected]d5b04b832013-09-12 19:48:1558} // namespace base