tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

process.h (12243B)


      1 // Copyright 2011 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_PROCESS_H_
      6 #define BASE_PROCESS_PROCESS_H_
      7 
      8 #include "base/base_export.h"
      9 #include "base/process/process_handle.h"
     10 #include "base/strings/string_piece.h"
     11 #include "base/time/time.h"
     12 #include "build/blink_buildflags.h"
     13 #include "build/build_config.h"
     14 #include "build/chromeos_buildflags.h"
     15 
     16 #if BUILDFLAG(IS_WIN)
     17 #include "base/win/scoped_handle.h"
     18 #endif
     19 
     20 #if BUILDFLAG(IS_FUCHSIA)
     21 #include <lib/zx/process.h>
     22 #endif
     23 
     24 #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
     25 #include "base/feature_list.h"
     26 #endif  // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
     27 
     28 #if BUILDFLAG(IS_APPLE)
     29 #include "base/process/port_provider_mac.h"
     30 #endif  // BUILDFLAG(IS_APPLE)
     31 
     32 namespace base {
     33 
     34 #if BUILDFLAG(IS_CHROMEOS)
     35 // OneGroupPerRenderer feature places each foreground renderer process into
     36 // its own cgroup. This will cause the scheduler to use the aggregate runtime
     37 // of all threads in the process when deciding on the next thread to schedule.
     38 // It will help guarantee fairness between renderers.
     39 BASE_EXPORT BASE_DECLARE_FEATURE(kOneGroupPerRenderer);
     40 
     41 // Set all threads of a background process as backgrounded, which changes the
     42 // thread attributes including c-group, latency sensitivity. But the nice value
     43 // is unchanged, since background process is under the spell of the background
     44 // CPU c-group (via cgroup.procs).
     45 BASE_EXPORT BASE_DECLARE_FEATURE(kSetThreadBgForBgProcess);
     46 #endif
     47 
     48 #if BUILDFLAG(IS_WIN)
     49 BASE_EXPORT BASE_DECLARE_FEATURE(kUseEcoQoSForBackgroundProcess);
     50 #endif
     51 
     52 // Provides a move-only encapsulation of a process.
     53 //
     54 // This object is not tied to the lifetime of the underlying process: the
     55 // process may be killed and this object may still around, and it will still
     56 // claim to be valid. The actual behavior in that case is OS dependent like so:
     57 //
     58 // Windows: The underlying ProcessHandle will be valid after the process dies
     59 // and can be used to gather some information about that process, but most
     60 // methods will obviously fail.
     61 //
     62 // POSIX: The underlying ProcessHandle is not guaranteed to remain valid after
     63 // the process dies, and it may be reused by the system, which means that it may
     64 // end up pointing to the wrong process.
     65 class BASE_EXPORT Process {
     66 public:
     67  // On Windows, this takes ownership of |handle|. On POSIX, this does not take
     68  // ownership of |handle|.
     69  explicit Process(ProcessHandle handle = kNullProcessHandle);
     70 
     71  Process(Process&& other);
     72 
     73  Process(const Process&) = delete;
     74  Process& operator=(const Process&) = delete;
     75 
     76  // The destructor does not terminate the process.
     77  ~Process();
     78 
     79  Process& operator=(Process&& other);
     80 
     81  // Returns an object for the current process.
     82  static Process Current();
     83 
     84  // Returns a Process for the given |pid|.
     85  static Process Open(ProcessId pid);
     86 
     87  // Returns a Process for the given |pid|. On Windows the handle is opened
     88  // with more access rights and must only be used by trusted code (can read the
     89  // address space and duplicate handles).
     90  static Process OpenWithExtraPrivileges(ProcessId pid);
     91 
     92 #if BUILDFLAG(IS_WIN)
     93  // Returns a Process for the given |pid|, using some |desired_access|.
     94  // See ::OpenProcess documentation for valid |desired_access|.
     95  static Process OpenWithAccess(ProcessId pid, DWORD desired_access);
     96 #endif
     97 
     98  // Returns true if changing the priority of processes through `SetPriority()`
     99  // is possible.
    100  static bool CanSetPriority();
    101 
    102  // Terminates the current process immediately with |exit_code|.
    103  [[noreturn]] static void TerminateCurrentProcessImmediately(int exit_code);
    104 
    105  // Returns true if this objects represents a valid process.
    106  bool IsValid() const;
    107 
    108  // Returns a handle for this process. There is no guarantee about when that
    109  // handle becomes invalid because this object retains ownership.
    110  ProcessHandle Handle() const;
    111 
    112  // Returns a second object that represents this process.
    113  Process Duplicate() const;
    114 
    115  // Relinquishes ownership of the handle and sets this to kNullProcessHandle.
    116  // The result may be a pseudo-handle, depending on the OS and value stored in
    117  // this.
    118  [[nodiscard]] ProcessHandle Release();
    119 
    120  // Get the PID for this process.
    121  ProcessId Pid() const;
    122 
    123  // Get the creation time for this process. Since the Pid can be reused after a
    124  // process dies, it is useful to use both the Pid and the creation time to
    125  // uniquely identify a process.
    126  //
    127  // On Android, works only if |this| is the current process, as security
    128  // features prevent an application from getting data about other processes,
    129  // even if they belong to us. Otherwise, returns Time().
    130  Time CreationTime() const;
    131 
    132  // Returns true if this process is the current process.
    133  bool is_current() const;
    134 
    135 #if BUILDFLAG(IS_CHROMEOS)
    136  // A unique token generated for each process, this is used to create a unique
    137  // cgroup for each renderer.
    138  const std::string& unique_token() const { return unique_token_; }
    139 #endif
    140 
    141  // Close the process handle. This will not terminate the process.
    142  void Close();
    143 
    144  // Returns true if this process is still running. This is only safe on Windows
    145  // (and maybe Fuchsia?), because the ProcessHandle will keep the zombie
    146  // process information available until itself has been released. But on Posix,
    147  // the OS may reuse the ProcessId.
    148 #if BUILDFLAG(IS_WIN)
    149  bool IsRunning() const {
    150    return !WaitForExitWithTimeout(base::TimeDelta(), nullptr);
    151  }
    152 #endif
    153 
    154  // Terminates the process with extreme prejudice. The given |exit_code| will
    155  // be the exit code of the process. If |wait| is true, this method will wait
    156  // for up to one minute for the process to actually terminate.
    157  // Returns true if the process terminates within the allowed time.
    158  // NOTE: |exit_code| is only used on OS_WIN.
    159  bool Terminate(int exit_code, bool wait) const;
    160 
    161 #if BUILDFLAG(IS_WIN)
    162  enum class WaitExitStatus {
    163    PROCESS_EXITED,
    164    STOP_EVENT_SIGNALED,
    165    FAILED,
    166  };
    167 
    168  // Waits for the process to exit, or the specified |stop_event_handle| to be
    169  // set. Returns value indicating which event was set. The given |exit_code|
    170  // will be the exit code of the process.
    171  WaitExitStatus WaitForExitOrEvent(
    172      const base::win::ScopedHandle& stop_event_handle,
    173      int* exit_code) const;
    174 #endif  // BUILDFLAG(IS_WIN)
    175 
    176  // Waits for the process to exit. Returns true on success.
    177  // On POSIX, if the process has been signaled then |exit_code| is set to -1.
    178  // On Linux this must be a child process, however on Mac and Windows it can be
    179  // any process.
    180  // NOTE: |exit_code| is optional, nullptr can be passed if the exit code is
    181  // not required.
    182  bool WaitForExit(int* exit_code) const;
    183 
    184  // Same as WaitForExit() but only waits for up to |timeout|.
    185  // NOTE: |exit_code| is optional, nullptr can be passed if the exit code
    186  // is not required.
    187  bool WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) const;
    188 
    189  // Indicates that the process has exited with the specified |exit_code|.
    190  // This should be called if process exit is observed outside of this class.
    191  // (i.e. Not because Terminate or WaitForExit, above, was called.)
    192  // Note that nothing prevents this being called multiple times for a dead
    193  // process though that should be avoided.
    194  void Exited(int exit_code) const;
    195 
    196  // The different priorities that a process can have.
    197  // TODO(pmonette): Consider merging with base::TaskPriority when the API is
    198  //                 stable.
    199  enum class Priority {
    200    // The process does not contribute to content that is currently important
    201    // to the user. Lowest priority.
    202    kBestEffort,
    203 
    204    // The process contributes to content that is visible to the user. High
    205    // priority.
    206    kUserVisible,
    207 
    208    // The process contributes to content that is of the utmost importance to
    209    // the user, like producing audible content, or visible content in the
    210    // focused window. Highest priority.
    211    kUserBlocking,
    212  };
    213 
    214 #if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && BUILDFLAG(USE_BLINK))
    215  // The Mac needs a Mach port in order to manipulate a process's priority,
    216  // and there's no good way to get that from base given the pid. These Mac
    217  // variants of the `GetPriority()` and `SetPriority()` API take a port
    218  // provider for this reason. See crbug.com/460102.
    219 
    220  // Retrieves the priority of the process. Defaults to Priority::kUserBlocking
    221  // if the priority could not be retrieved, or if `port_provider` is null.
    222  Priority GetPriority(PortProvider* port_provider) const;
    223 
    224  // Sets the priority of the process process. Returns true if the priority was
    225  // changed, false otherwise. If `port_provider` is null, this is a no-op and
    226  // it returns false.
    227  bool SetPriority(PortProvider* port_provider, Priority priority);
    228 #else
    229  // Retrieves the priority of the process. Defaults to Priority::kUserBlocking
    230  // if the priority could not be retrieved.
    231  Priority GetPriority() const;
    232 
    233  // Sets the priority of the process process. Returns true if the priority was
    234  // changed, false otherwise.
    235  bool SetPriority(Priority priority);
    236 #endif  // BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && BUILDFLAG(USE_BLINK))
    237 
    238  // Returns an integer representing the priority of a process. The meaning
    239  // of this value is OS dependent.
    240  int GetOSPriority() const;
    241 
    242 #if BUILDFLAG(IS_CHROMEOS_ASH)
    243  // Get the PID in its PID namespace.
    244  // If the process is not in a PID namespace or /proc/<pid>/status does not
    245  // report NSpid, kNullProcessId is returned.
    246  ProcessId GetPidInNamespace() const;
    247 #endif
    248 
    249 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
    250  // Returns true if the process has any seccomp policy applied.
    251  bool IsSeccompSandboxed();
    252 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
    253 
    254 #if BUILDFLAG(IS_CHROMEOS)
    255  // Exposes OneGroupPerRendererEnabled() to unit tests.
    256  static bool OneGroupPerRendererEnabledForTesting();
    257 
    258  // If OneGroupPerRenderer is enabled, runs at process startup to clean up
    259  // any stale cgroups that were left behind from any unclean exits of the
    260  // browser process.
    261  static void CleanUpStaleProcessStates();
    262 
    263  // Initializes the process's priority. If OneGroupPerRenderer is enabled, it
    264  // creates a unique cgroup for the process. This should be called before
    265  // SetPriority(). This is a no-op if the Process is not valid or if it has
    266  // already been called.
    267  void InitializePriority();
    268 #endif  // BUILDFLAG(IS_CHROMEOS)
    269 
    270 #if BUILDFLAG(IS_APPLE)
    271  // Sets the priority of the current process to its default value.
    272  static void SetCurrentTaskDefaultRole();
    273 #endif  // BUILDFLAG(IS_MAC)
    274 
    275 private:
    276 #if BUILDFLAG(IS_CHROMEOS)
    277  // Cleans up process state. If OneGroupPerRenderer is enabled, it cleans up
    278  // the cgroup created by InitializePriority(). If the process has not
    279  // fully terminated yet, it will post a background task to try again.
    280  void CleanUpProcess(int remaining_retries) const;
    281 
    282  // Calls CleanUpProcess() on a background thread.
    283  void CleanUpProcessAsync() const;
    284 
    285  // Used to call CleanUpProcess() on a background thread because Process is not
    286  // refcounted.
    287  static void CleanUpProcessScheduled(Process process, int remaining_retries);
    288 #endif  // BUILDFLAG(IS_CHROMEOS)
    289 
    290 #if BUILDFLAG(IS_WIN)
    291  win::ScopedHandle process_;
    292 #elif BUILDFLAG(IS_FUCHSIA)
    293  zx::process process_;
    294 #else
    295  ProcessHandle process_;
    296 #endif
    297 
    298 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
    299  bool is_current_process_;
    300 #endif
    301 
    302 #if BUILDFLAG(IS_CHROMEOS)
    303  // A unique token per process not per class instance (`base::Process`). This
    304  // is similar to the PID of a process but should not be reused after the
    305  // process's termination. The token will be copied during Duplicate()
    306  // and move semantics as is the PID/ProcessHandle.
    307  std::string unique_token_;
    308 #endif
    309 };
    310 
    311 #if BUILDFLAG(IS_CHROMEOS)
    312 // Exposed for testing.
    313 // Given the contents of the /proc/<pid>/cgroup file, determine whether the
    314 // process is backgrounded or not.
    315 BASE_EXPORT Process::Priority GetProcessPriorityCGroup(
    316    const StringPiece& cgroup_contents);
    317 #endif  // BUILDFLAG(IS_CHROMEOS)
    318 
    319 }  // namespace base
    320 
    321 #endif  // BASE_PROCESS_PROCESS_H_