diff options
Diffstat (limited to 'chromium/components/metrics/child_call_stack_profile_collector.h')
-rw-r--r-- | chromium/components/metrics/child_call_stack_profile_collector.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/chromium/components/metrics/child_call_stack_profile_collector.h b/chromium/components/metrics/child_call_stack_profile_collector.h new file mode 100644 index 00000000000..adc356d110f --- /dev/null +++ b/chromium/components/metrics/child_call_stack_profile_collector.h @@ -0,0 +1,120 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_METRICS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_ +#define COMPONENTS_METRICS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/lock.h" +#include "components/metrics/public/interfaces/call_stack_profile_collector.mojom.h" + +namespace shell { +class InterfaceProvider; +} + +namespace metrics { + +// ChildCallStackProfileCollector collects stacks at startup, caching them +// internally until a CallStackProfileCollector interface is available. If a +// CallStackProfileCollector is provided via the InterfaceProvider supplied to +// SetParentProfileCollector, the cached stacks are sent via that interface. All +// future stacks received via callbacks supplied by GetProfilerCallback are sent +// via that interface as well. +// +// If no CallStackProfileCollector is provided via InterfaceProvider, any cached +// stacks and all future stacks received via callbacks supplied by +// GetProfilerCallback are flushed. In typical usage this should not happen +// because the browser is expected to always supply a CallStackProfileCollector. +// +// This class is only necessary if a CallStackProfileCollector is not available +// at the time the profiler is created. Otherwise the CallStackProfileCollector +// can be used directly. +// +// To use, create as a leaky lazy instance: +// +// base::LazyInstance<metrics::ChildCallStackProfileCollector>::Leaky +// g_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER; +// +// Then, invoke CreateCompletedCallback() to generate the CompletedCallback to +// pass when creating the StackSamplingProfiler. +// +// When the mojo InterfaceProvider becomes available, provide it via +// SetParentProfileCollector(). +class ChildCallStackProfileCollector { + public: + ChildCallStackProfileCollector(); + ~ChildCallStackProfileCollector(); + + // Get a callback for use with StackSamplingProfiler that provides completed + // profiles to this object. The callback should be immediately passed to the + // StackSamplingProfiler, and should not be reused between + // StackSamplingProfilers. This function may be called on any thread. + base::StackSamplingProfiler::CompletedCallback GetProfilerCallback( + const CallStackProfileParams& params); + + // Sets the CallStackProfileCollector interface from |parent_collector|. This + // function MUST be invoked exactly once, regardless of whether + // |parent_collector| is null, as it flushes pending data in either case. + void SetParentProfileCollector( + metrics::mojom::CallStackProfileCollectorPtr parent_collector); + + private: + friend class ChildCallStackProfileCollectorTest; + + // Bundles together a set of collected profiles and the collection state for + // storage, pending availability of the parent mojo interface. + struct ProfilesState { + ProfilesState(); + ProfilesState(const ProfilesState&); + ProfilesState( + const CallStackProfileParams& params, + base::TimeTicks start_timestamp, + const base::StackSamplingProfiler::CallStackProfiles& profiles); + ~ProfilesState(); + + CallStackProfileParams params; + base::TimeTicks start_timestamp; + + // The sampled profiles. + base::StackSamplingProfiler::CallStackProfiles profiles; + }; + + using CallStackProfile = base::StackSamplingProfiler::CallStackProfile; + + void Collect(const CallStackProfileParams& params, + base::TimeTicks start_timestamp, + const std::vector<CallStackProfile>& profiles); + + // This object may be accessed on any thread, including the profiler + // thread. The expected use case for the object is to be created and have + // GetProfilerCallback before the message loop starts, which prevents the use + // of PostTask and the like for inter-thread communication. + base::Lock lock_; + + // Whether to retain profiles when the interface is not set. Remains true + // until the invocation of SetParentProfileCollector(), at which point it is + // false for the rest of the object lifetime. + bool retain_profiles_ = true; + + // The task runner associated with the parent interface. + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + // The interface to use to collect the stack profiles provided to this + // object. Initially null until SetParentProfileCollector() is invoked, at + // which point it may either become set or remain null. If set, stacks are + // collected via the interface, otherwise they are ignored. + mojom::CallStackProfileCollectorPtr parent_collector_; + + // Profiles being cached by this object, pending a parent interface to be + // supplied. + std::vector<ProfilesState> profiles_; + + DISALLOW_COPY_AND_ASSIGN(ChildCallStackProfileCollector); +}; + +} // namespace metrics + +#endif // COMPONENTS_METRICS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_ |