xref: /aosp_15_r20/external/cronet/components/metrics/call_stacks/child_call_stack_profile_collector.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 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 COMPONENTS_METRICS_CALL_STACKS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_
6 #define COMPONENTS_METRICS_CALL_STACKS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/memory/ref_counted.h"
12 #include "base/synchronization/lock.h"
13 #include "base/task/single_thread_task_runner.h"
14 #include "base/time/time.h"
15 #include "components/metrics/public/mojom/call_stack_profile_collector.mojom.h"
16 #include "mojo/public/cpp/bindings/pending_remote.h"
17 #include "mojo/public/cpp/bindings/remote.h"
18 
19 namespace service_manager {
20 class InterfaceProvider;
21 }
22 
23 namespace metrics {
24 
25 class SampledProfile;
26 
27 // ChildCallStackProfileCollector collects stacks at startup, caching them
28 // internally until a CallStackProfileCollector interface is available. If a
29 // CallStackProfileCollector is provided via the InterfaceProvider supplied to
30 // SetParentProfileCollector, the cached stacks are sent via that interface. All
31 // future stacks received via callbacks supplied by GetProfilerCallback are sent
32 // via that interface as well.
33 //
34 // If no CallStackProfileCollector is provided via InterfaceProvider, any cached
35 // stacks and all future stacks received via callbacks supplied by
36 // GetProfilerCallback are flushed. In typical usage this should not happen
37 // because the browser is expected to always supply a CallStackProfileCollector.
38 //
39 // This class is only necessary if a CallStackProfileCollector is not available
40 // at the time the profiler is created. Otherwise the CallStackProfileCollector
41 // can be used directly.
42 //
43 // CallStackProfileBuilder owns and manages a ChildCallStackProfileCollector. It
44 // invokes Collect() in CallStackProfileBuilder::OnProfileCompleted() to collect
45 // a profile.
46 //
47 // When the mojo InterfaceProvider becomes available, provide it via
48 // SetParentProfileCollector().
49 class ChildCallStackProfileCollector {
50  public:
51   ChildCallStackProfileCollector();
52 
53   ChildCallStackProfileCollector(const ChildCallStackProfileCollector&) =
54       delete;
55   ChildCallStackProfileCollector& operator=(
56       const ChildCallStackProfileCollector&) = delete;
57 
58   ~ChildCallStackProfileCollector();
59 
60   // Sets the CallStackProfileCollector interface from |parent_collector|. This
61   // function MUST be invoked exactly once, regardless of whether
62   // |parent_collector| is mojo::NullRemote(), as it flushes pending data in
63   // either case.
64   void SetParentProfileCollector(
65       mojo::PendingRemote<metrics::mojom::CallStackProfileCollector>
66           parent_collector);
67 
68   // Collects |profile| whose collection start time is |start_timestamp|.
69   void Collect(base::TimeTicks start_timestamp, SampledProfile profile);
70 
71  private:
72   friend class ChildCallStackProfileCollectorTest;
73 
74   // Bundles together a collected serialized profile and the collection state
75   // for storage, pending availability of the parent mojo interface.
76   struct ProfileState {
77     ProfileState();
78     // |profile| can be very large and must be passed with std::move.
79     ProfileState(base::TimeTicks start_timestamp,
80                  mojom::ProfileType profile_type,
81                  std::string&& profile);
82 
83     ProfileState(const ProfileState&) = delete;
84     ProfileState& operator=(const ProfileState&) = delete;
85 
86     ProfileState(ProfileState&&);
87 
88     ~ProfileState();
89 
90     ProfileState& operator=(ProfileState&&);
91 
92     base::TimeTicks start_timestamp;
93     mojom::ProfileType profile_type;
94 
95     // The serialized sampled profile.
96     std::string profile;
97   };
98 
99   // This object may be accessed on any thread, including the profiler
100   // thread. The expected use case for the object is to be created and have
101   // GetProfilerCallback before the message loop starts, which prevents the use
102   // of PostTask and the like for inter-thread communication.
103   base::Lock lock_;
104 
105   // Whether to retain the profile when the interface is not set. Remains true
106   // until the invocation of SetParentProfileCollector(), at which point it is
107   // false for the rest of the object lifetime.
108   bool retain_profiles_ = true;
109 
110   // The task runner associated with the parent interface.
111   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
112 
113   // The interface to use to collect the stack profiles provided to this
114   // object. Initially mojo::NullRemote() until SetParentProfileCollector() is
115   // invoked, at which point it may either become set or remain
116   // mojo::NullRemote(). If set, stacks are collected via the interface,
117   // otherwise they are ignored.
118   mojo::Remote<mojom::CallStackProfileCollector> parent_collector_;
119 
120   // Profiles being cached by this object, pending a parent interface to be
121   // supplied.
122   std::vector<ProfileState> profiles_;
123 };
124 
125 }  // namespace metrics
126 
127 #endif  // COMPONENTS_METRICS_CALL_STACKS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_
128