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 <kwiberg@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Markus Handell <handellm@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32584}
This commit is contained in:
@ -54,6 +54,7 @@ rtc_source_set("callback_list") {
|
|||||||
"callback_list.h",
|
"callback_list.h",
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
|
":checks",
|
||||||
":untyped_function",
|
":untyped_function",
|
||||||
"../api:function_view",
|
"../api:function_view",
|
||||||
"system:assume",
|
"system:assume",
|
||||||
|
@ -10,17 +10,25 @@
|
|||||||
|
|
||||||
#include "rtc_base/callback_list.h"
|
#include "rtc_base/callback_list.h"
|
||||||
|
|
||||||
|
#include "rtc_base/checks.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace callback_list_impl {
|
namespace callback_list_impl {
|
||||||
|
|
||||||
CallbackListReceivers::CallbackListReceivers() = default;
|
CallbackListReceivers::CallbackListReceivers() = default;
|
||||||
CallbackListReceivers::~CallbackListReceivers() = default;
|
|
||||||
|
CallbackListReceivers::~CallbackListReceivers() {
|
||||||
|
RTC_CHECK(!send_in_progress_);
|
||||||
|
}
|
||||||
|
|
||||||
void CallbackListReceivers::Foreach(
|
void CallbackListReceivers::Foreach(
|
||||||
rtc::FunctionView<void(UntypedFunction&)> fv) {
|
rtc::FunctionView<void(UntypedFunction&)> fv) {
|
||||||
|
RTC_CHECK(!send_in_progress_);
|
||||||
|
send_in_progress_ = true;
|
||||||
for (auto& r : receivers_) {
|
for (auto& r : receivers_) {
|
||||||
fv(r);
|
fv(r);
|
||||||
}
|
}
|
||||||
|
send_in_progress_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template void CallbackListReceivers::AddReceiver(
|
template void CallbackListReceivers::AddReceiver(
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/function_view.h"
|
#include "api/function_view.h"
|
||||||
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/system/assume.h"
|
#include "rtc_base/system/assume.h"
|
||||||
#include "rtc_base/system/inline.h"
|
#include "rtc_base/system/inline.h"
|
||||||
#include "rtc_base/untyped_function.h"
|
#include "rtc_base/untyped_function.h"
|
||||||
@ -33,6 +34,7 @@ class CallbackListReceivers {
|
|||||||
|
|
||||||
template <typename UntypedFunctionArgsT>
|
template <typename UntypedFunctionArgsT>
|
||||||
RTC_NO_INLINE void AddReceiver(UntypedFunctionArgsT args) {
|
RTC_NO_INLINE void AddReceiver(UntypedFunctionArgsT args) {
|
||||||
|
RTC_CHECK(!send_in_progress_);
|
||||||
receivers_.push_back(UntypedFunction::Create(args));
|
receivers_.push_back(UntypedFunction::Create(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ class CallbackListReceivers {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<UntypedFunction> receivers_;
|
std::vector<UntypedFunction> receivers_;
|
||||||
|
bool send_in_progress_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern template void CallbackListReceivers::AddReceiver(
|
extern template void CallbackListReceivers::AddReceiver(
|
||||||
@ -145,7 +148,9 @@ class CallbackList {
|
|||||||
UntypedFunction::PrepareArgs<void(ArgT...)>(std::forward<F>(f)));
|
UntypedFunction::PrepareArgs<void(ArgT...)>(std::forward<F>(f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls all receivers with the given arguments.
|
// Calls all receivers with the given arguments. While the Send is in
|
||||||
|
// progress, no method calls are allowed; specifically, this means that the
|
||||||
|
// callbacks may not do anything with this CallbackList instance.
|
||||||
template <typename... ArgU>
|
template <typename... ArgU>
|
||||||
void Send(ArgU&&... args) {
|
void Send(ArgU&&... args) {
|
||||||
receivers_.Foreach([&](UntypedFunction& f) {
|
receivers_.Foreach([&](UntypedFunction& f) {
|
||||||
|
Reference in New Issue
Block a user