// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_OBSERVER_LIST_THREADSAFE_H_ #define BASE_OBSERVER_LIST_THREADSAFE_H_ #include <unordered_map> #include <utility> #include "base/auto_reset.h" #include "base/base_export.h" #include "base/check.h" #include "base/check_op.h" #include "base/containers/contains.h" #include "base/dcheck_is_on.h" #include "base/debug/stack_trace.h" #include "base/functional/bind.h" #include "base/location.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" #include "base/strings/strcat.h" #include "base/synchronization/lock.h" #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "build/build_config.h" #include "third_party/abseil-cpp/absl/base/attributes.h" /////////////////////////////////////////////////////////////////////////////// // // OVERVIEW: // // A thread-safe container for a list of observers. This is similar to the // observer_list (see observer_list.h), but it is more robust for multi- // threaded situations. // // The following use cases are supported: // * Observers can register for notifications from any sequence. They are // always notified on the sequence from which they were registered. // * Any sequence may trigger a notification via Notify(). // * Observers can remove themselves from the observer list inside of a // callback. // * If one sequence is notifying observers concurrently with an observer // removing itself from the observer list, the notifications will be // silently dropped. However if the observer is currently inside a // notification callback, the callback will finish running. // // By default, observers can be removed from any sequence. However this can be // error-prone since an observer may be running a callback when it's removed, // in which case it isn't safe to delete until the callback is finished. // Consider using the RemoveObserverPolicy::kAddingSequenceOnly template // parameter, which will CHECK that observers are only removed from the // sequence where they were added (which is also the sequence that runs // callbacks). // // The drawback of the threadsafe observer list is that notifications are not // as real-time as the non-threadsafe version of this class. Notifications // will always be done via PostTask() to another sequence, whereas with the // non-thread-safe ObserverList, notifications happen synchronously. // // Note: this class previously supported synchronous notifications for // same-sequence observers, but it was error-prone and removed in // crbug.com/1193750, think twice before re-considering this paradigm. // /////////////////////////////////////////////////////////////////////////////// namespace base { namespace internal { class BASE_EXPORT ObserverListThreadSafeBase : public RefCountedThreadSafe<ObserverListThreadSafeBase> { … }; } // namespace internal enum class RemoveObserverPolicy { … }; template <class ObserverType, RemoveObserverPolicy RemovePolicy = RemoveObserverPolicy::kAnySequence> class ObserverListThreadSafe : public internal::ObserverListThreadSafeBase { … }; } // namespace base #endif // BASE_OBSERVER_LIST_THREADSAFE_H_