xref: /aosp_15_r20/external/cronet/base/allocator/dispatcher/dispatcher.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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