1 // Copyright 2024 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_FUNCTIONAL_CONCURRENT_CLOSURES_H_ 6 #define BASE_FUNCTIONAL_CONCURRENT_CLOSURES_H_ 7 8 #include "base/base_export.h" 9 #include "base/functional/callback.h" 10 #include "base/location.h" 11 #include "base/memory/raw_ptr.h" 12 #include "base/task/bind_post_task.h" 13 14 namespace base { 15 16 // OVERVIEW: 17 // 18 // ConcurrentClosures is a OnceClosure version of ConcurrentCallbacks<T> and an 19 // alternative to BarrierClosure, it dispenses OnceClosures via CreateClosure() 20 // and invokes the closure passed to Done() after all prior closures have been 21 // run. 22 // 23 // ConcurrentClosures is intended to be used over BarrierClosure in 24 // cases where the count is unknown prior to requiring a closure to start a 25 // task, and for cases where the count is manually derived from the code and 26 // subject to human error. 27 // 28 // IMPORTANT NOTES: 29 // 30 // - ConcurrentClosures is NOT thread safe. 31 // - The done closure will NOT be run synchronously, it will be PostTask() to 32 // the sequence that Done() was invoked on. 33 // - ConcurrentClosures cannot be used after Done() is called, a CHECK verifies 34 // this. 35 // 36 // TYPICAL USAGE: 37 // 38 // void DoABC(OnceClosure closure) { 39 // base::ConcurrentClosures concurrent; 40 // 41 // DoA(concurrent.CreateClosure()); 42 // DoB(concurrent.CreateClosure()); 43 // DoC(concurrent.CreateClosure()); 44 // 45 // std::move(concurrent).Done(closure); 46 // } 47 48 class BASE_EXPORT ConcurrentClosures { 49 public: 50 ConcurrentClosures(); 51 ~ConcurrentClosures(); 52 53 // Create a closure for the done closure to wait for. 54 [[nodiscard]] OnceClosure CreateClosure(); 55 56 // Finish creating concurrent closures and provide done closure to run once 57 // all prior closures have executed. 58 // `this` is no longer usable after calling Done(), must be called with 59 // std::move(). 60 void Done(OnceClosure done_closure, const Location& location = FROM_HERE) &&; 61 62 private: 63 class Info { 64 public: 65 Info(); 66 ~Info(); 67 68 void Run(); 69 70 size_t pending_ = 0u; 71 OnceClosure done_closure_; 72 }; 73 74 RepeatingClosure info_run_closure_; 75 // info_ is owned by info_run_closure_. 76 raw_ptr<Info> info_; 77 }; 78 79 } // namespace base 80 81 #endif // BASE_FUNCTIONAL_CONCURRENT_CLOSURES_H_ 82