Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame^] | 1 | // Copyright 2013 The Chromium Authors |
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 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 | |||||
tzik | 34bf605 | 2017-04-27 14:03:21 | [diff] [blame] | 7 | #include <utility> |
8 | |||||
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 9 | #include "base/atomic_ref_count.h" |
10 | #include "base/bind.h" | ||||
tzik | 34bf605 | 2017-04-27 14:03:21 | [diff] [blame] | 11 | #include "base/memory/ptr_util.h" |
Peter Kasting | 9f9d8e3 | 2021-08-12 01:14:54 | [diff] [blame] | 12 | #include "base/numerics/safe_conversions.h" |
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 13 | |
tzik | 34bf605 | 2017-04-27 14:03:21 | [diff] [blame] | 14 | namespace base { |
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 15 | namespace { |
16 | |||||
17 | // Maintains state for a BarrierClosure. | ||||
18 | class BarrierInfo { | ||||
19 | public: | ||||
Peter Kasting | 9f9d8e3 | 2021-08-12 01:14:54 | [diff] [blame] | 20 | BarrierInfo(size_t num_callbacks_left, OnceClosure done_closure); |
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 21 | void Run(); |
22 | |||||
23 | private: | ||||
tzik | 34bf605 | 2017-04-27 14:03:21 | [diff] [blame] | 24 | AtomicRefCount num_callbacks_left_; |
25 | OnceClosure done_closure_; | ||||
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 26 | }; |
27 | |||||
Peter Kasting | 9f9d8e3 | 2021-08-12 01:14:54 | [diff] [blame] | 28 | BarrierInfo::BarrierInfo(size_t num_callbacks, OnceClosure done_closure) |
29 | : num_callbacks_left_(checked_cast<int>(num_callbacks)), | ||||
tzik | 34bf605 | 2017-04-27 14:03:21 | [diff] [blame] | 30 | done_closure_(std::move(done_closure)) {} |
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 31 | |
32 | void BarrierInfo::Run() { | ||||
Jeremy Roman | ee96d56 | 2017-07-06 19:09:36 | [diff] [blame] | 33 | DCHECK(!num_callbacks_left_.IsZero()); |
34 | if (!num_callbacks_left_.Decrement()) | ||||
tzik | 34bf605 | 2017-04-27 14:03:21 | [diff] [blame] | 35 | std::move(done_closure_).Run(); |
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 36 | } |
37 | |||||
cfredric | e7af064 | 2021-07-27 21:06:51 | [diff] [blame] | 38 | void ShouldNeverRun() { |
39 | CHECK(false); | ||||
40 | } | ||||
41 | |||||
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 42 | } // namespace |
43 | |||||
Peter Kasting | 9f9d8e3 | 2021-08-12 01:14:54 | [diff] [blame] | 44 | RepeatingClosure BarrierClosure(size_t num_callbacks_left, |
tzik | 34bf605 | 2017-04-27 14:03:21 | [diff] [blame] | 45 | OnceClosure done_closure) { |
cfredric | e7af064 | 2021-07-27 21:06:51 | [diff] [blame] | 46 | if (num_callbacks_left == 0) { |
tzik | 34bf605 | 2017-04-27 14:03:21 | [diff] [blame] | 47 | std::move(done_closure).Run(); |
cfredric | e7af064 | 2021-07-27 21:06:51 | [diff] [blame] | 48 | return BindRepeating(&ShouldNeverRun); |
49 | } | ||||
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 50 | |
cfredric | e7af064 | 2021-07-27 21:06:51 | [diff] [blame] | 51 | return BindRepeating(&BarrierInfo::Run, |
52 | std::make_unique<BarrierInfo>(num_callbacks_left, | ||||
53 | std::move(done_closure))); | ||||
[email protected] | 285d06fc | 2013-08-24 15:00:33 | [diff] [blame] | 54 | } |
55 | |||||
[email protected] | d5b04b83 | 2013-09-12 19:48:15 | [diff] [blame] | 56 | } // namespace base |