xref: /aosp_15_r20/external/libchrome/base/barrier_closure.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/barrier_closure.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <utility>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include "base/atomic_ref_count.h"
10*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
12*635a8641SAndroid Build Coastguard Worker 
13*635a8641SAndroid Build Coastguard Worker namespace base {
14*635a8641SAndroid Build Coastguard Worker namespace {
15*635a8641SAndroid Build Coastguard Worker 
16*635a8641SAndroid Build Coastguard Worker // Maintains state for a BarrierClosure.
17*635a8641SAndroid Build Coastguard Worker class BarrierInfo {
18*635a8641SAndroid Build Coastguard Worker  public:
19*635a8641SAndroid Build Coastguard Worker   BarrierInfo(int num_callbacks_left, OnceClosure done_closure);
20*635a8641SAndroid Build Coastguard Worker   void Run();
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker  private:
23*635a8641SAndroid Build Coastguard Worker   AtomicRefCount num_callbacks_left_;
24*635a8641SAndroid Build Coastguard Worker   OnceClosure done_closure_;
25*635a8641SAndroid Build Coastguard Worker };
26*635a8641SAndroid Build Coastguard Worker 
BarrierInfo(int num_callbacks,OnceClosure done_closure)27*635a8641SAndroid Build Coastguard Worker BarrierInfo::BarrierInfo(int num_callbacks, OnceClosure done_closure)
28*635a8641SAndroid Build Coastguard Worker     : num_callbacks_left_(num_callbacks),
29*635a8641SAndroid Build Coastguard Worker       done_closure_(std::move(done_closure)) {}
30*635a8641SAndroid Build Coastguard Worker 
Run()31*635a8641SAndroid Build Coastguard Worker void BarrierInfo::Run() {
32*635a8641SAndroid Build Coastguard Worker   DCHECK(!num_callbacks_left_.IsZero());
33*635a8641SAndroid Build Coastguard Worker   if (!num_callbacks_left_.Decrement())
34*635a8641SAndroid Build Coastguard Worker     std::move(done_closure_).Run();
35*635a8641SAndroid Build Coastguard Worker }
36*635a8641SAndroid Build Coastguard Worker 
37*635a8641SAndroid Build Coastguard Worker }  // namespace
38*635a8641SAndroid Build Coastguard Worker 
BarrierClosure(int num_callbacks_left,OnceClosure done_closure)39*635a8641SAndroid Build Coastguard Worker RepeatingClosure BarrierClosure(int num_callbacks_left,
40*635a8641SAndroid Build Coastguard Worker                                 OnceClosure done_closure) {
41*635a8641SAndroid Build Coastguard Worker   DCHECK_GE(num_callbacks_left, 0);
42*635a8641SAndroid Build Coastguard Worker 
43*635a8641SAndroid Build Coastguard Worker   if (num_callbacks_left == 0)
44*635a8641SAndroid Build Coastguard Worker     std::move(done_closure).Run();
45*635a8641SAndroid Build Coastguard Worker 
46*635a8641SAndroid Build Coastguard Worker   return BindRepeating(
47*635a8641SAndroid Build Coastguard Worker       &BarrierInfo::Run,
48*635a8641SAndroid Build Coastguard Worker       Owned(new BarrierInfo(num_callbacks_left, std::move(done_closure))));
49*635a8641SAndroid Build Coastguard Worker }
50*635a8641SAndroid Build Coastguard Worker 
51*635a8641SAndroid Build Coastguard Worker }  // namespace base
52