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 #include "base/functional/concurrent_closures.h" 6 7 #include "base/functional/bind.h" 8 #include "base/task/sequenced_task_runner.h" 9 10 namespace base { 11 ConcurrentClosures()12ConcurrentClosures::ConcurrentClosures() { 13 auto info_owner = std::make_unique<Info>(); 14 info_ = info_owner.get(); 15 info_run_closure_ = BindRepeating(&Info::Run, std::move(info_owner)); 16 } 17 ConcurrentClosures::~ConcurrentClosures() = default; 18 CreateClosure()19OnceClosure ConcurrentClosures::CreateClosure() { 20 CHECK(info_); 21 ++info_->pending_; 22 return info_run_closure_; 23 } 24 Done(OnceClosure done_closure,const Location & location)25void ConcurrentClosures::Done(OnceClosure done_closure, 26 const Location& location) && { 27 CHECK(info_); 28 info_->done_closure_ = BindPostTask(SequencedTaskRunner::GetCurrentDefault(), 29 std::move(done_closure), location); 30 if (info_->pending_ == 0u) { 31 std::move(info_->done_closure_).Run(); 32 } 33 info_ = nullptr; 34 } 35 36 ConcurrentClosures::Info::Info() = default; 37 38 ConcurrentClosures::Info::~Info() = default; 39 Run()40void ConcurrentClosures::Info::Run() { 41 CHECK_GT(pending_, 0u); 42 --pending_; 43 if (done_closure_ && pending_ == 0u) { 44 SequencedTaskRunner::GetCurrentDefault()->PostTask( 45 FROM_HERE, std::move(done_closure_)); 46 } 47 } 48 49 } // namespace base 50