Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 01a36f3

Browse files
Karl WibergCommit Bot
authored andcommitted
CallbackList: Don't allow reentrancy
When a Send is in progress, don't allow modification to the list of callbacks, or a recursive Send. Bug: webrtc:11943 Change-Id: I88751060136972d0c9170db725fa30312a14b5b1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/192360 Commit-Queue: Karl Wiberg <[email protected]> Reviewed-by: Niels Moller <[email protected]> Reviewed-by: Markus Handell <[email protected]> Cr-Commit-Position: refs/heads/master@{#32584}
1 parent b249d0a commit 01a36f3

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

rtc_base/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ rtc_source_set("callback_list") {
5454
"callback_list.h",
5555
]
5656
deps = [
57+
":checks",
5758
":untyped_function",
5859
"../api:function_view",
5960
"system:assume",

rtc_base/callback_list.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,25 @@
1010

1111
#include "rtc_base/callback_list.h"
1212

13+
#include "rtc_base/checks.h"
14+
1315
namespace webrtc {
1416
namespace callback_list_impl {
1517

1618
CallbackListReceivers::CallbackListReceivers() = default;
17-
CallbackListReceivers::~CallbackListReceivers() = default;
19+
20+
CallbackListReceivers::~CallbackListReceivers() {
21+
RTC_CHECK(!send_in_progress_);
22+
}
1823

1924
void CallbackListReceivers::Foreach(
2025
rtc::FunctionView<void(UntypedFunction&)> fv) {
26+
RTC_CHECK(!send_in_progress_);
27+
send_in_progress_ = true;
2128
for (auto& r : receivers_) {
2229
fv(r);
2330
}
31+
send_in_progress_ = false;
2432
}
2533

2634
template void CallbackListReceivers::AddReceiver(

rtc_base/callback_list.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <vector>
1616

1717
#include "api/function_view.h"
18+
#include "rtc_base/checks.h"
1819
#include "rtc_base/system/assume.h"
1920
#include "rtc_base/system/inline.h"
2021
#include "rtc_base/untyped_function.h"
@@ -33,13 +34,15 @@ class CallbackListReceivers {
3334

3435
template <typename UntypedFunctionArgsT>
3536
RTC_NO_INLINE void AddReceiver(UntypedFunctionArgsT args) {
37+
RTC_CHECK(!send_in_progress_);
3638
receivers_.push_back(UntypedFunction::Create(args));
3739
}
3840

3941
void Foreach(rtc::FunctionView<void(UntypedFunction&)> fv);
4042

4143
private:
4244
std::vector<UntypedFunction> receivers_;
45+
bool send_in_progress_ = false;
4346
};
4447

4548
extern template void CallbackListReceivers::AddReceiver(
@@ -145,7 +148,9 @@ class CallbackList {
145148
UntypedFunction::PrepareArgs<void(ArgT...)>(std::forward<F>(f)));
146149
}
147150

148-
// Calls all receivers with the given arguments.
151+
// Calls all receivers with the given arguments. While the Send is in
152+
// progress, no method calls are allowed; specifically, this means that the
153+
// callbacks may not do anything with this CallbackList instance.
149154
template <typename... ArgU>
150155
void Send(ArgU&&... args) {
151156
receivers_.Foreach([&](UntypedFunction& f) {

0 commit comments

Comments
 (0)