blob: 020b2743e8852c9a779a591af882d9cfaf31055f [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"
10#include "base/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);
[email protected]285d06fc2013-08-24 15:00:3321 void Run();
22
23 private:
tzik34bf6052017-04-27 14:03:2124 AtomicRefCount num_callbacks_left_;
25 OnceClosure done_closure_;
[email protected]285d06fc2013-08-24 15:00:3326};
27
Peter Kasting9f9d8e32021-08-12 01:14:5428BarrierInfo::BarrierInfo(size_t num_callbacks, OnceClosure done_closure)
29 : num_callbacks_left_(checked_cast<int>(num_callbacks)),
tzik34bf6052017-04-27 14:03:2130 done_closure_(std::move(done_closure)) {}
[email protected]285d06fc2013-08-24 15:00:3331
32void BarrierInfo::Run() {
Jeremy Romanee96d562017-07-06 19:09:3633 DCHECK(!num_callbacks_left_.IsZero());
34 if (!num_callbacks_left_.Decrement())
tzik34bf6052017-04-27 14:03:2135 std::move(done_closure_).Run();
[email protected]285d06fc2013-08-24 15:00:3336}
37
cfredrice7af0642021-07-27 21:06:5138void ShouldNeverRun() {
39 CHECK(false);
40}
41
[email protected]285d06fc2013-08-24 15:00:3342} // namespace
43
Peter Kasting9f9d8e32021-08-12 01:14:5444RepeatingClosure BarrierClosure(size_t num_callbacks_left,
tzik34bf6052017-04-27 14:03:2145 OnceClosure done_closure) {
cfredrice7af0642021-07-27 21:06:5146 if (num_callbacks_left == 0) {
tzik34bf6052017-04-27 14:03:2147 std::move(done_closure).Run();
cfredrice7af0642021-07-27 21:06:5148 return BindRepeating(&ShouldNeverRun);
49 }
[email protected]285d06fc2013-08-24 15:00:3350
cfredrice7af0642021-07-27 21:06:5151 return BindRepeating(&BarrierInfo::Run,
52 std::make_unique<BarrierInfo>(num_callbacks_left,
53 std::move(done_closure)));
[email protected]285d06fc2013-08-24 15:00:3354}
55
[email protected]d5b04b832013-09-12 19:48:1556} // namespace base