1 /* 2 * Copyright 2019 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "rtc_base/operations_chain.h" 12 13 #include "rtc_base/checks.h" 14 15 namespace rtc { 16 CallbackHandle(scoped_refptr<OperationsChain> operations_chain)17OperationsChain::CallbackHandle::CallbackHandle( 18 scoped_refptr<OperationsChain> operations_chain) 19 : operations_chain_(std::move(operations_chain)) {} 20 ~CallbackHandle()21OperationsChain::CallbackHandle::~CallbackHandle() { 22 RTC_DCHECK(has_run_); 23 } 24 OnOperationComplete()25void OperationsChain::CallbackHandle::OnOperationComplete() { 26 RTC_DCHECK(!has_run_); 27 #ifdef RTC_DCHECK_IS_ON 28 has_run_ = true; 29 #endif // RTC_DCHECK_IS_ON 30 operations_chain_->OnOperationComplete(); 31 // We have no reason to keep the |operations_chain_| alive through reference 32 // counting anymore. 33 operations_chain_ = nullptr; 34 } 35 36 // static Create()37scoped_refptr<OperationsChain> OperationsChain::Create() { 38 return new OperationsChain(); 39 } 40 OperationsChain()41OperationsChain::OperationsChain() : RefCountedObject() { 42 RTC_DCHECK_RUN_ON(&sequence_checker_); 43 } 44 ~OperationsChain()45OperationsChain::~OperationsChain() { 46 // Operations keep the chain alive through reference counting so this should 47 // not be possible. The fact that the chain is empty makes it safe to 48 // destroy the OperationsChain on any sequence. 49 RTC_DCHECK(chained_operations_.empty()); 50 } 51 CreateOperationsChainCallback()52std::function<void()> OperationsChain::CreateOperationsChainCallback() { 53 return [handle = rtc::scoped_refptr<CallbackHandle>( 54 new CallbackHandle(this))]() { handle->OnOperationComplete(); }; 55 } 56 OnOperationComplete()57void OperationsChain::OnOperationComplete() { 58 RTC_DCHECK_RUN_ON(&sequence_checker_); 59 // The front element is the operation that just completed, remove it. 60 RTC_DCHECK(!chained_operations_.empty()); 61 chained_operations_.pop(); 62 // If there are any other operations chained, execute the next one. 63 if (!chained_operations_.empty()) { 64 chained_operations_.front()->Run(); 65 } 66 } 67 68 } // namespace rtc 69