blob: 0ad5882fef2903a3a3ddb7e1f23336c2a538e2a1 [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
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"
[email protected]285d06fc2013-08-24 15:00:3312
tzik34bf6052017-04-27 14:03:2113namespace base {
[email protected]285d06fc2013-08-24 15:00:3314namespace {
15
16// Maintains state for a BarrierClosure.
17class BarrierInfo {
18 public:
tzik34bf6052017-04-27 14:03:2119 BarrierInfo(int num_callbacks_left, OnceClosure done_closure);
[email protected]285d06fc2013-08-24 15:00:3320 void Run();
21
22 private:
tzik34bf6052017-04-27 14:03:2123 AtomicRefCount num_callbacks_left_;
24 OnceClosure done_closure_;
[email protected]285d06fc2013-08-24 15:00:3325};
26
tzik34bf6052017-04-27 14:03:2127BarrierInfo::BarrierInfo(int num_callbacks, OnceClosure done_closure)
[email protected]285d06fc2013-08-24 15:00:3328 : num_callbacks_left_(num_callbacks),
tzik34bf6052017-04-27 14:03:2129 done_closure_(std::move(done_closure)) {}
[email protected]285d06fc2013-08-24 15:00:3330
31void BarrierInfo::Run() {
Jeremy Romanee96d562017-07-06 19:09:3632 DCHECK(!num_callbacks_left_.IsZero());
33 if (!num_callbacks_left_.Decrement())
tzik34bf6052017-04-27 14:03:2134 std::move(done_closure_).Run();
[email protected]285d06fc2013-08-24 15:00:3335}
36
cfredrice7af0642021-07-27 21:06:5137void ShouldNeverRun() {
38 CHECK(false);
39}
40
[email protected]285d06fc2013-08-24 15:00:3341} // namespace
42
tzik34bf6052017-04-27 14:03:2143RepeatingClosure BarrierClosure(int num_callbacks_left,
44 OnceClosure done_closure) {
danakj94219a212015-03-09 22:27:2545 DCHECK_GE(num_callbacks_left, 0);
[email protected]285d06fc2013-08-24 15:00:3346
cfredrice7af0642021-07-27 21:06:5147 if (num_callbacks_left == 0) {
tzik34bf6052017-04-27 14:03:2148 std::move(done_closure).Run();
cfredrice7af0642021-07-27 21:06:5149 return BindRepeating(&ShouldNeverRun);
50 }
[email protected]285d06fc2013-08-24 15:00:3351
cfredrice7af0642021-07-27 21:06:5152 return BindRepeating(&BarrierInfo::Run,
53 std::make_unique<BarrierInfo>(num_callbacks_left,
54 std::move(done_closure)));
[email protected]285d06fc2013-08-24 15:00:3355}
56
[email protected]d5b04b832013-09-12 19:48:1557} // namespace base