File: current_process.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (164 lines) | stat: -rw-r--r-- 5,402 bytes parent folder | download | duplicates (3)
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_