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 DCHECK_CALLED_ON_VALID_SEQUENCE(info_->sequence_checker_); 22 ++info_->pending_; 23 return info_run_closure_; 24 } 25 Done(OnceClosure done_closure,const Location & location)26void ConcurrentClosures::Done(OnceClosure done_closure, 27 const Location& location) && { 28 CHECK(info_); 29 DCHECK_CALLED_ON_VALID_SEQUENCE(info_->sequence_checker_); 30 info_->done_closure_ = BindPostTask(SequencedTaskRunner::GetCurrentDefault(), 31 std::move(done_closure), location); 32 if (info_->pending_ == 0u) { 33 std::move(info_->done_closure_).Run(); 34 } 35 info_ = nullptr; 36 } 37 38 ConcurrentClosures::Info::Info() = default; 39 40 ConcurrentClosures::Info::~Info() = default; 41 Run()42void ConcurrentClosures::Info::Run() { 43 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 44 CHECK_GT(pending_, 0u); 45 --pending_; 46 if (done_closure_ && pending_ == 0u) { 47 SequencedTaskRunner::GetCurrentDefault()->PostTask( 48 FROM_HERE, std::move(done_closure_)); 49 } 50 } 51 52 } // namespace base 53