1 // Copyright 2022 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_ALLOCATOR_DISPATCHER_DISPATCHER_H_ 6 #define BASE_ALLOCATOR_DISPATCHER_DISPATCHER_H_ 7 8 #include "base/allocator/dispatcher/internal/dispatcher_internal.h" 9 #include "base/base_export.h" 10 11 #include <memory> 12 13 namespace base::allocator::dispatcher { 14 15 namespace internal { 16 struct DispatchData; 17 } 18 19 // Dispatcher serves as the top level instance for managing the dispatch 20 // mechanism. The class instance manages connections to the various memory 21 // subsystems such as PartitionAlloc. To keep the public interface as lean as 22 // possible it uses a pimpl pattern. 23 class BASE_EXPORT Dispatcher { 24 public: 25 static Dispatcher& GetInstance(); 26 27 Dispatcher(); 28 29 // Initialize the dispatch mechanism with the given tuple of observers. The 30 // observers must be valid (it is only DCHECKed internally at initialization, 31 // but not verified further) 32 // If Initialize is called multiple times, the first one wins. All later 33 // invocations are silently ignored. Initialization is protected from 34 // concurrent invocations. In case of concurrent accesses, the first one to 35 // get the lock wins. 36 // The dispatcher invokes following functions on the observers: 37 // void OnAllocation(void* address, 38 // size_t size, 39 // AllocationSubsystem sub_system, 40 // const char* type_name); 41 // void OnFree(void* address); 42 // 43 // Note: The dispatcher mechanism does NOT bring systematic protection against 44 // recursive invocations. That is, observers which allocate memory on the 45 // heap, i.e. through dynamically allocated containers or by using the 46 // CHECK-macro, are responsible to break these recursions! 47 template <typename... ObserverTypes> Initialize(const std::tuple<ObserverTypes...> & observers)48 void Initialize(const std::tuple<ObserverTypes...>& observers) { 49 // Get the hooks for running these observers and pass them to further 50 // initialization 51 Initialize(internal::GetNotificationHooks(observers)); 52 } 53 54 // The following functions provide an interface to setup and tear down the 55 // dispatcher when testing. This must NOT be used from production code since 56 // the hooks cannot be removed reliably under all circumstances. 57 template <typename ObserverType> InitializeForTesting(ObserverType * observer)58 void InitializeForTesting(ObserverType* observer) { 59 Initialize(std::make_tuple(observer)); 60 } 61 62 void ResetForTesting(); 63 64 private: 65 // structure and pointer to the private implementation. 66 struct Impl; 67 std::unique_ptr<Impl> const impl_; 68 69 ~Dispatcher(); 70 71 void Initialize(const internal::DispatchData& dispatch_data); 72 }; 73 } // namespace base::allocator::dispatcher 74 75 #endif // BASE_ALLOCATOR_DISPATCHER_DISPATCHER_H_ 76