blob: 68ee20babcfd8c975aeb430d8efc545b377b84a1 [file] [log] [blame]
Henrik Boström27c29362019-10-21 15:21:55 +02001/*
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
15namespace rtc {
16
17OperationsChain::CallbackHandle::CallbackHandle(
18 scoped_refptr<OperationsChain> operations_chain)
19 : operations_chain_(std::move(operations_chain)) {}
20
21OperationsChain::CallbackHandle::~CallbackHandle() {
22 RTC_DCHECK(has_run_);
23}
24
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
37scoped_refptr<OperationsChain> OperationsChain::Create() {
38 return new OperationsChain();
39}
40
41OperationsChain::OperationsChain() : RefCountedObject() {
42 RTC_DCHECK_RUN_ON(&sequence_checker_);
43}
44
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
52std::function<void()> OperationsChain::CreateOperationsChainCallback() {
53 return [handle = rtc::scoped_refptr<CallbackHandle>(
54 new CallbackHandle(this))]() { handle->OnOperationComplete(); };
55}
56
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