blob: af08b5a9c875d2aaa7082d91fca93f529a0dee92 [file] [log] [blame]
// 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/no_destructor.h"
#include "base/process/process_handle.h"
#include "base/synchronization/lock.h"
#include "base/trace_event/base_tracing.h"
#include "build/buildflag.h"
namespace tracing {
class TraceEventDataSource;
class CustomEventRecorder;
void SetProcessTrackDescriptor(int64_t process_start_timestamp);
} // namespace tracing
namespace mojo::core {
class Channel;
}
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 void ::tracing::SetProcessTrackDescriptor(
int64_t process_start_timestamp);
friend class ::mojo::core::Channel;
};
// 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 static_cast<CurrentProcessType>(
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 void ::tracing::SetProcessTrackDescriptor(
int64_t process_start_timestamp);
};
std::string GetName(NameKey key) {
AutoLock lock(lock_);
return process_name_;
}
// 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);
void SetProcessNameAndType(const std::string& process_name,
CurrentProcessType process_type);
bool IsProcessNameEmpty() const {
AutoLock lock(lock_);
return process_name_.empty();
}
private:
friend class base::NoDestructor<CurrentProcess>;
CurrentProcess() = default;
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_;
};
} // namespace base
#endif // BASE_PROCESS_CURRENT_PROCESS_H_