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