diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index a4d209eef0..6ee7190125 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -54,6 +54,7 @@ rtc_source_set("callback_list") { "callback_list.h", ] deps = [ + ":checks", ":untyped_function", "../api:function_view", "system:assume", diff --git a/rtc_base/callback_list.cc b/rtc_base/callback_list.cc index 0b1de8e7ba..ac947e2258 100644 --- a/rtc_base/callback_list.cc +++ b/rtc_base/callback_list.cc @@ -10,17 +10,25 @@ #include "rtc_base/callback_list.h" +#include "rtc_base/checks.h" + namespace webrtc { namespace callback_list_impl { CallbackListReceivers::CallbackListReceivers() = default; -CallbackListReceivers::~CallbackListReceivers() = default; + +CallbackListReceivers::~CallbackListReceivers() { + RTC_CHECK(!send_in_progress_); +} void CallbackListReceivers::Foreach( rtc::FunctionView fv) { + RTC_CHECK(!send_in_progress_); + send_in_progress_ = true; for (auto& r : receivers_) { fv(r); } + send_in_progress_ = false; } template void CallbackListReceivers::AddReceiver( diff --git a/rtc_base/callback_list.h b/rtc_base/callback_list.h index 59da8eeb81..659b838d02 100644 --- a/rtc_base/callback_list.h +++ b/rtc_base/callback_list.h @@ -15,6 +15,7 @@ #include #include "api/function_view.h" +#include "rtc_base/checks.h" #include "rtc_base/system/assume.h" #include "rtc_base/system/inline.h" #include "rtc_base/untyped_function.h" @@ -33,6 +34,7 @@ class CallbackListReceivers { template RTC_NO_INLINE void AddReceiver(UntypedFunctionArgsT args) { + RTC_CHECK(!send_in_progress_); receivers_.push_back(UntypedFunction::Create(args)); } @@ -40,6 +42,7 @@ class CallbackListReceivers { private: std::vector receivers_; + bool send_in_progress_ = false; }; extern template void CallbackListReceivers::AddReceiver( @@ -145,7 +148,9 @@ class CallbackList { UntypedFunction::PrepareArgs(std::forward(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 void Send(ArgU&&... args) { receivers_.Foreach([&](UntypedFunction& f) {