1 // Copyright 2017 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_TRACE_EVENT_MEMORY_DUMP_PROVIDER_INFO_H_ 6 #define BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_INFO_H_ 7 8 #include <memory> 9 #include <set> 10 11 #include "base/base_export.h" 12 #include "base/memory/raw_ptr.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/trace_event/memory_dump_provider.h" 15 16 namespace base { 17 18 class SequencedTaskRunner; 19 20 namespace trace_event { 21 22 // Wraps a MemoryDumpProvider (MDP), which is registered via 23 // MemoryDumpManager(MDM)::RegisterDumpProvider(), holding the extra information 24 // required to deal with it (which task runner it should be invoked onto, 25 // whether it has been disabled, etc.) 26 // More importantly, having a refptr to this object guarantees that a MDP that 27 // is not thread-bound (hence which can only be unregistered via 28 // MDM::UnregisterAndDeleteDumpProviderSoon()) will stay alive as long as the 29 // refptr is held. 30 // 31 // Lifetime: 32 // At any time, there is at most one instance of this class for each instance 33 // of a given MemoryDumpProvider, but there might be several scoped_refptr 34 // holding onto each of this. Specifically: 35 // - In nominal conditions, there is a refptr for each registered MDP in the 36 // MDM's |dump_providers_| list. 37 // - In most cases, the only refptr (in the |dump_providers_| list) is destroyed 38 // by MDM::UnregisterDumpProvider(). 39 // - However, when MDM starts a dump, the list of refptrs is copied into the 40 // ProcessMemoryDumpAsyncState. That list is pruned as MDP(s) are invoked. 41 // - If UnregisterDumpProvider() is called on a non-thread-bound MDP while a 42 // dump is in progress, the extar extra of the handle is destroyed in 43 // MDM::SetupNextMemoryDump() or MDM::InvokeOnMemoryDump(), when the copy 44 // inside ProcessMemoryDumpAsyncState is erase()-d. 45 // - The PeakDetector can keep extra refptrs when enabled. 46 struct BASE_EXPORT MemoryDumpProviderInfo 47 : public RefCountedThreadSafe<MemoryDumpProviderInfo> { 48 public: 49 // Define a total order based on the |task_runner| affinity, so that MDPs 50 // belonging to the same SequencedTaskRunner are adjacent in the set. 51 struct Comparator { 52 bool operator()(const scoped_refptr<MemoryDumpProviderInfo>& a, 53 const scoped_refptr<MemoryDumpProviderInfo>& b) const; 54 }; 55 using OrderedSet = 56 std::set<scoped_refptr<MemoryDumpProviderInfo>, Comparator>; 57 58 MemoryDumpProviderInfo(MemoryDumpProvider* dump_provider, 59 const char* name, 60 scoped_refptr<SequencedTaskRunner> task_runner, 61 const MemoryDumpProvider::Options& options, 62 bool allowed_in_background_mode); 63 64 MemoryDumpProviderInfo(const MemoryDumpProviderInfo&) = delete; 65 MemoryDumpProviderInfo& operator=(const MemoryDumpProviderInfo&) = delete; 66 67 // These non-const fields below, instead, are not thread safe and can be 68 // mutated only: 69 // - On the |task_runner|, when not null (i.e. for thread-bound MDPS). 70 // - By the MDM's background thread (or in any other way that guarantees 71 // sequencing) for non-thread-bound MDPs. 72 73 // Used to transfer ownership for UnregisterAndDeleteDumpProviderSoon(). 74 // nullptr in all other cases. 75 // We need to declare this before `dump_provider`, because it might sometimes 76 // own the pointer it is referencing. Thus, we need this to be destroyed after 77 // `dump_provider`. 78 std::unique_ptr<MemoryDumpProvider> owned_dump_provider; 79 80 // It is safe to access the const fields below from any thread as they are 81 // never mutated. 82 const raw_ptr<MemoryDumpProvider, AcrossTasksDanglingUntriaged> dump_provider; 83 84 // The |options| arg passed to MDM::RegisterDumpProvider(). 85 const MemoryDumpProvider::Options options; 86 87 // Human readable name, not unique (distinct MDP instances might have the same 88 // name). Used for debugging, testing and allowing for BACKGROUND mode. 89 const char* const name; 90 91 // The task runner on which the MDP::OnMemoryDump call should be posted onto. 92 // Can be nullptr, in which case the MDP will be invoked on a background 93 // thread handled by MDM. 94 const scoped_refptr<SequencedTaskRunner> task_runner; 95 96 // True if the dump provider is allowed for background mode. 97 const bool allowed_in_background_mode; 98 99 // For fail-safe logic (auto-disable failing MDPs). 100 int consecutive_failures; 101 102 // Flagged either by the auto-disable logic or during unregistration. 103 bool disabled; 104 105 private: 106 friend class base::RefCountedThreadSafe<MemoryDumpProviderInfo>; 107 ~MemoryDumpProviderInfo(); 108 }; 109 110 } // namespace trace_event 111 } // namespace base 112 113 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_INFO_H_ 114