| /* | |
| * Copyright 2025 The WebRTC Project Authors. All rights reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #ifndef RTC_BASE_CALLBACK_LIST_WITH_LOCKS_H_ | |
| #define RTC_BASE_CALLBACK_LIST_WITH_LOCKS_H_ | |
| #include <utility> | |
| #include "rtc_base/callback_list.h" | |
| #include "rtc_base/synchronization/mutex.h" | |
| #include "rtc_base/thread_annotations.h" | |
| namespace webrtc { | |
| // This class wraps a CallbackList in a mutex, so that the methods | |
| // can be called from any thread. | |
| // Note that recursive calls *will* cause a deadlock. | |
| // TOOD: https://issues.webrtc.org/457303638 - remove the need for locks. | |
| template <typename... ArgT> | |
| class CallbackListWithLocks { | |
| public: | |
| CallbackListWithLocks() = default; | |
| CallbackListWithLocks(const CallbackListWithLocks&) = delete; | |
| CallbackListWithLocks& operator=(const CallbackListWithLocks&) = delete; | |
| CallbackListWithLocks(CallbackListWithLocks&&) = delete; | |
| CallbackListWithLocks& operator=(CallbackListWithLocks&&) = delete; | |
| // Adds a new receiver. The receiver (a callable object or a function pointer) | |
| // must be movable, but need not be copyable. Its call signature should be | |
| // `void(ArgT...)`. The removal tag is a pointer to an arbitrary object that | |
| // you own, and that will stay alive until the CallbackList is gone, or until | |
| // all receivers using it as a removal tag have been removed; you can use it | |
| // to remove the receiver. | |
| template <typename F> | |
| void AddReceiver(const void* removal_tag, F&& f) { | |
| MutexLock lock(&callback_mutex_); | |
| callbacks_.AddReceiver(removal_tag, std::forward<F>(f)); | |
| } | |
| // Adds a new receiver with no removal tag. | |
| template <typename F> | |
| void AddReceiver(F&& f) { | |
| MutexLock lock(&callback_mutex_); | |
| callbacks_.AddReceiver(std::forward<F>(f)); | |
| } | |
| // Removes all receivers that were added with the given removal tag. | |
| // Must not be called from within a callback. | |
| void RemoveReceivers(const void* removal_tag) { | |
| MutexLock lock(&callback_mutex_); | |
| callbacks_.RemoveReceivers(removal_tag); | |
| } | |
| // 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. | |
| // | |
| // Note: Receivers are called serially, but not necessarily in the same order | |
| // they were added. | |
| template <typename... ArgU> | |
| void Send(ArgU&&... args) { | |
| MutexLock lock(&callback_mutex_); | |
| callbacks_.Send(std::forward<ArgU...>(args...)); | |
| } | |
| private: | |
| Mutex callback_mutex_; | |
| CallbackList<ArgT...> callbacks_ RTC_GUARDED_BY(callback_mutex_); | |
| }; | |
| } // namespace webrtc | |
| #endif // RTC_BASE_CALLBACK_LIST_WITH_LOCKS_H_ |