1*6777b538SAndroid Build Coastguard Worker // Copyright 2024 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #include "base/functional/concurrent_closures.h" 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h" 8*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h" 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker namespace base { 11*6777b538SAndroid Build Coastguard Worker ConcurrentClosures()12*6777b538SAndroid Build Coastguard WorkerConcurrentClosures::ConcurrentClosures() { 13*6777b538SAndroid Build Coastguard Worker auto info_owner = std::make_unique<Info>(); 14*6777b538SAndroid Build Coastguard Worker info_ = info_owner.get(); 15*6777b538SAndroid Build Coastguard Worker info_run_closure_ = BindRepeating(&Info::Run, std::move(info_owner)); 16*6777b538SAndroid Build Coastguard Worker } 17*6777b538SAndroid Build Coastguard Worker ConcurrentClosures::~ConcurrentClosures() = default; 18*6777b538SAndroid Build Coastguard Worker CreateClosure()19*6777b538SAndroid Build Coastguard WorkerOnceClosure ConcurrentClosures::CreateClosure() { 20*6777b538SAndroid Build Coastguard Worker CHECK(info_); 21*6777b538SAndroid Build Coastguard Worker ++info_->pending_; 22*6777b538SAndroid Build Coastguard Worker return info_run_closure_; 23*6777b538SAndroid Build Coastguard Worker } 24*6777b538SAndroid Build Coastguard Worker Done(OnceClosure done_closure,const Location & location)25*6777b538SAndroid Build Coastguard Workervoid ConcurrentClosures::Done(OnceClosure done_closure, 26*6777b538SAndroid Build Coastguard Worker const Location& location) && { 27*6777b538SAndroid Build Coastguard Worker CHECK(info_); 28*6777b538SAndroid Build Coastguard Worker info_->done_closure_ = BindPostTask(SequencedTaskRunner::GetCurrentDefault(), 29*6777b538SAndroid Build Coastguard Worker std::move(done_closure), location); 30*6777b538SAndroid Build Coastguard Worker if (info_->pending_ == 0u) { 31*6777b538SAndroid Build Coastguard Worker std::move(info_->done_closure_).Run(); 32*6777b538SAndroid Build Coastguard Worker } 33*6777b538SAndroid Build Coastguard Worker info_ = nullptr; 34*6777b538SAndroid Build Coastguard Worker } 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker ConcurrentClosures::Info::Info() = default; 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Worker ConcurrentClosures::Info::~Info() = default; 39*6777b538SAndroid Build Coastguard Worker Run()40*6777b538SAndroid Build Coastguard Workervoid ConcurrentClosures::Info::Run() { 41*6777b538SAndroid Build Coastguard Worker CHECK_GT(pending_, 0u); 42*6777b538SAndroid Build Coastguard Worker --pending_; 43*6777b538SAndroid Build Coastguard Worker if (done_closure_ && pending_ == 0u) { 44*6777b538SAndroid Build Coastguard Worker SequencedTaskRunner::GetCurrentDefault()->PostTask( 45*6777b538SAndroid Build Coastguard Worker FROM_HERE, std::move(done_closure_)); 46*6777b538SAndroid Build Coastguard Worker } 47*6777b538SAndroid Build Coastguard Worker } 48*6777b538SAndroid Build Coastguard Worker 49*6777b538SAndroid Build Coastguard Worker } // namespace base 50