1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_PROCESS_CURRENT_PROCESS_H_
#define BASE_PROCESS_CURRENT_PROCESS_H_
#include <atomic>
#include <string>
#include "base/base_export.h"
#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
#include "base/process/process_handle.h"
#include "base/synchronization/lock.h"
#include "build/buildflag.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h"
namespace tracing {
class TraceEventDataSource;
class CustomEventRecorder;
class TrackNameRecorder;
} // namespace tracing
namespace mojo::core {
class Channel;
}
namespace network {
class ContentDecodingInterceptor;
} // namespace network
namespace base {
namespace test {
class CurrentProcessForTest;
} // namespace test
using CurrentProcessType =
perfetto::protos::pbzero::ChromeProcessDescriptor::ProcessType;
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// Use coalesced service process for recording histograms.
enum class ShortProcessType {
kUnspecified = 0,
kBrowser = 1,
kRenderer = 2,
kUtility = 3,
kZygote = 4,
kSandboxHelper = 5,
kGpu = 6,
kPpapiPlugin = 7,
kPpapiBroker = 8,
kServiceNetwork = 9,
kServiceStorage = 10,
kService = 11,
kRendererExtension = 12,
kMaxValue = kRendererExtension,
};
// CurrentProcess class provides access to set of current process properties
// which are accessible only from the process itself (e.g. ProcessType,
// ProcessName).
// See base::CurrentThread for access to properties of the running
// thread and base::Process::Current for the properties which are known both
// from within and without the process (e.g. pid).
class BASE_EXPORT CurrentProcess {
public:
static CurrentProcess& GetInstance();
CurrentProcess(const CurrentProcess&) = delete;
CurrentProcess& operator=(const CurrentProcess&) = delete;
~CurrentProcess();
bool operator==(const CurrentProcess& other) const;
class TypeKey {
private:
TypeKey() = default;
friend class ::base::test::CurrentProcessForTest;
friend class ::tracing::TraceEventDataSource;
friend class ::tracing::CustomEventRecorder;
friend class ::tracing::TrackNameRecorder;
friend class ::mojo::core::Channel;
friend class ::network::ContentDecodingInterceptor;
};
// Returns an enum corresponding to the type of the current process (e.g.
// browser / renderer / utility / etc). It can be used in metrics or tracing
// code — for example, to split a number of low-level events with
// process-type-agnostic implementation (e.g. number of posted tasks) by
// process type for diagnostic purposes.
// To avoid layering violations (i.e. //base or other low-level code modifying
// its behaviour based on the //chrome or //content-level concepts like a
// "browser" or "renderer" process), the access to this function is controlled
// by an explicit list.
CurrentProcessType GetType(TypeKey key) {
return process_type_.load(std::memory_order_relaxed);
}
ShortProcessType GetShortType(TypeKey key);
class NameKey {
private:
NameKey() = default;
friend class ::base::test::CurrentProcessForTest;
friend class ::tracing::TraceEventDataSource;
friend class ::tracing::TrackNameRecorder;
};
std::string GetName(NameKey key) {
AutoLock lock(lock_);
return process_name_;
}
class BASE_EXPORT Delegate {
public:
// Called on the main thread of the process whose name is changing,
// immediately after the name is set.
virtual void OnProcessNameChanged(const std::string& process_name,
CurrentProcessType process_type) = 0;
protected:
~Delegate() = default;
};
// Sets the name and type of the process for the metrics and tracing. This
// function should be called as early as possible in the process's lifetime
// before starting any threads, typically in *Main() function. Provide
// process_name as an argument if it can't be trivially derived from the
// process type.
void SetProcessType(CurrentProcessType process_type);
// `delegate` might racily be invoked after resetting, thus its lifetime must
// match `CurrentProcess`.
void SetDelegate(Delegate* delegate, NameKey key);
bool IsProcessNameEmpty() const {
AutoLock lock(lock_);
return process_name_.empty();
}
private:
friend class base::NoDestructor<CurrentProcess>;
CurrentProcess() = default;
void SetProcessNameAndType(const std::string& process_name,
CurrentProcessType process_type);
mutable Lock lock_;
std::string process_name_;
// The process_type_ is set at the startup before processes start running.
// However, since it runs in multi-threaded environment and if has to be
// changed later, we would want well-defined behaviour even if one thread
// writes while another reads. There are some processes (e.g. Service process)
// where we don't have a guarantee that it will be called early enough in the
// process's lifetime, thus we use std::atomic here.
std::atomic<CurrentProcessType> process_type_;
raw_ptr<Delegate> delegate_;
};
} // namespace base
#endif // BASE_PROCESS_CURRENT_PROCESS_H_
|