Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame] | 1 | // Copyright 2011 The Chromium Authors |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
danakj | 0a44860 | 2015-03-10 00:31:16 | [diff] [blame] | 5 | #ifndef BASE_PROCESS_PROCESS_H_ |
| 6 | #define BASE_PROCESS_PROCESS_H_ |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 7 | |
Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 8 | #include <string_view> |
| 9 | |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 10 | #include "base/base_export.h" |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 11 | #include "base/process/process_handle.h" |
rvargas | 126fd582 | 2014-12-12 00:25:14 | [diff] [blame] | 12 | #include "base/time/time.h" |
Dave Tapuska | ed322d0 | 2023-03-07 23:33:33 | [diff] [blame] | 13 | #include "build/blink_buildflags.h" |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 14 | #include "build/build_config.h" |
Hidehiko Abe | 7c68f58 | 2020-09-03 15:47:25 | [diff] [blame] | 15 | #include "build/chromeos_buildflags.h" |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 16 | |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 17 | #if BUILDFLAG(IS_WIN) |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 18 | #include "base/win/scoped_handle.h" |
| 19 | #endif |
| 20 | |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 21 | #if BUILDFLAG(IS_FUCHSIA) |
Wez | 157707d6 | 2018-07-10 22:48:47 | [diff] [blame] | 22 | #include <lib/zx/process.h> |
Wez | 78b73313 | 2017-08-09 18:41:59 | [diff] [blame] | 23 | #endif |
| 24 | |
Zheda Chen | 2808be7 | 2022-12-19 06:26:55 | [diff] [blame] | 25 | #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) |
lgrey | 0d2bafc | 2016-11-07 16:28:33 | [diff] [blame] | 26 | #include "base/feature_list.h" |
Zheda Chen | 2808be7 | 2022-12-19 06:26:55 | [diff] [blame] | 27 | #endif // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 28 | |
| 29 | #if BUILDFLAG(IS_APPLE) |
lgrey | 0d2bafc | 2016-11-07 16:28:33 | [diff] [blame] | 30 | #include "base/process/port_provider_mac.h" |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 31 | #endif // BUILDFLAG(IS_APPLE) |
lgrey | 0d2bafc | 2016-11-07 16:28:33 | [diff] [blame] | 32 | |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 33 | namespace base { |
| 34 | |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 35 | #if BUILDFLAG(IS_CHROMEOS) |
| 36 | // OneGroupPerRenderer feature places each foreground renderer process into |
| 37 | // its own cgroup. This will cause the scheduler to use the aggregate runtime |
| 38 | // of all threads in the process when deciding on the next thread to schedule. |
| 39 | // It will help guarantee fairness between renderers. |
Daniel Cheng | 0fff5c23 | 2022-09-21 17:43:34 | [diff] [blame] | 40 | BASE_EXPORT BASE_DECLARE_FEATURE(kOneGroupPerRenderer); |
Joel Fernandes | f3f294f | 2023-09-22 17:29:45 | [diff] [blame] | 41 | |
| 42 | // Set all threads of a background process as backgrounded, which changes the |
| 43 | // thread attributes including c-group, latency sensitivity. But the nice value |
| 44 | // is unchanged, since background process is under the spell of the background |
| 45 | // CPU c-group (via cgroup.procs). |
| 46 | BASE_EXPORT BASE_DECLARE_FEATURE(kSetThreadBgForBgProcess); |
Shintaro Kawamura | f29c8fdf | 2024-03-28 03:40:08 | [diff] [blame] | 47 | |
| 48 | class ProcessPriorityDelegate; |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 49 | #endif |
| 50 | |
Zheda Chen | 2808be7 | 2022-12-19 06:26:55 | [diff] [blame] | 51 | #if BUILDFLAG(IS_WIN) |
| 52 | BASE_EXPORT BASE_DECLARE_FEATURE(kUseEcoQoSForBackgroundProcess); |
Zheda Chen | e7421f3 | 2024-08-29 03:05:39 | [diff] [blame^] | 53 | |
| 54 | BASE_EXPORT BASE_DECLARE_FEATURE(kEnableIntermediatePriority); |
Zheda Chen | 2808be7 | 2022-12-19 06:26:55 | [diff] [blame] | 55 | #endif |
| 56 | |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 57 | // Provides a move-only encapsulation of a process. |
| 58 | // |
| 59 | // This object is not tied to the lifetime of the underlying process: the |
| 60 | // process may be killed and this object may still around, and it will still |
| 61 | // claim to be valid. The actual behavior in that case is OS dependent like so: |
| 62 | // |
| 63 | // Windows: The underlying ProcessHandle will be valid after the process dies |
| 64 | // and can be used to gather some information about that process, but most |
| 65 | // methods will obviously fail. |
| 66 | // |
Wez | 6fcf59f | 2017-08-02 21:09:05 | [diff] [blame] | 67 | // POSIX: The underlying ProcessHandle is not guaranteed to remain valid after |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 68 | // the process dies, and it may be reused by the system, which means that it may |
| 69 | // end up pointing to the wrong process. |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 70 | class BASE_EXPORT Process { |
| 71 | public: |
erikchen | 7cef7d26 | 2017-09-11 22:56:57 | [diff] [blame] | 72 | // On Windows, this takes ownership of |handle|. On POSIX, this does not take |
| 73 | // ownership of |handle|. |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 74 | explicit Process(ProcessHandle handle = kNullProcessHandle); |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 75 | |
dcheng | e1b0277c | 2015-12-01 12:09:52 | [diff] [blame] | 76 | Process(Process&& other); |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 77 | |
Peter Boström | 7319bbd | 2021-09-15 22:59:38 | [diff] [blame] | 78 | Process(const Process&) = delete; |
| 79 | Process& operator=(const Process&) = delete; |
| 80 | |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 81 | // The destructor does not terminate the process. |
thakis | 3096dac | 2015-04-20 16:44:48 | [diff] [blame] | 82 | ~Process(); |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 83 | |
dcheng | e1b0277c | 2015-12-01 12:09:52 | [diff] [blame] | 84 | Process& operator=(Process&& other); |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 85 | |
| 86 | // Returns an object for the current process. |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 87 | static Process Current(); |
| 88 | |
rvargas | 6b039c37 | 2015-02-04 21:11:29 | [diff] [blame] | 89 | // Returns a Process for the given |pid|. |
| 90 | static Process Open(ProcessId pid); |
| 91 | |
rvargas | 747ff24 | 2015-01-17 02:46:47 | [diff] [blame] | 92 | // Returns a Process for the given |pid|. On Windows the handle is opened |
| 93 | // with more access rights and must only be used by trusted code (can read the |
| 94 | // address space and duplicate handles). |
rvargas | 1c376a8 | 2015-03-16 23:03:52 | [diff] [blame] | 95 | static Process OpenWithExtraPrivileges(ProcessId pid); |
rvargas | 747ff24 | 2015-01-17 02:46:47 | [diff] [blame] | 96 | |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 97 | #if BUILDFLAG(IS_WIN) |
rvargas | 17a407d | 2015-01-23 20:36:44 | [diff] [blame] | 98 | // Returns a Process for the given |pid|, using some |desired_access|. |
| 99 | // See ::OpenProcess documentation for valid |desired_access|. |
| 100 | static Process OpenWithAccess(ProcessId pid, DWORD desired_access); |
| 101 | #endif |
| 102 | |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 103 | // Returns true if changing the priority of processes through `SetPriority()` |
| 104 | // is possible. |
| 105 | static bool CanSetPriority(); |
| 106 | |
haraken | 940efb9 | 2017-02-08 05:58:15 | [diff] [blame] | 107 | // Terminates the current process immediately with |exit_code|. |
Wez | 5f11741 | 2018-02-07 04:17:47 | [diff] [blame] | 108 | [[noreturn]] static void TerminateCurrentProcessImmediately(int exit_code); |
haraken | 940efb9 | 2017-02-08 05:58:15 | [diff] [blame] | 109 | |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 110 | // Returns true if this objects represents a valid process. |
| 111 | bool IsValid() const; |
| 112 | |
| 113 | // Returns a handle for this process. There is no guarantee about when that |
| 114 | // handle becomes invalid because this object retains ownership. |
| 115 | ProcessHandle Handle() const; |
| 116 | |
| 117 | // Returns a second object that represents this process. |
| 118 | Process Duplicate() const; |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 119 | |
Robert Sesek | 0e7f165a | 2020-11-20 21:31:45 | [diff] [blame] | 120 | // Relinquishes ownership of the handle and sets this to kNullProcessHandle. |
| 121 | // The result may be a pseudo-handle, depending on the OS and value stored in |
| 122 | // this. |
Daniel Cheng | 4455c984 | 2022-01-13 23:26:37 | [diff] [blame] | 123 | [[nodiscard]] ProcessHandle Release(); |
Robert Sesek | 0e7f165a | 2020-11-20 21:31:45 | [diff] [blame] | 124 | |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 125 | // Get the PID for this process. |
rvargas | 960db88 | 2015-01-24 00:27:25 | [diff] [blame] | 126 | ProcessId Pid() const; |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 127 | |
Francois Doray | 7d131534 | 2018-10-21 03:54:47 | [diff] [blame] | 128 | // Get the creation time for this process. Since the Pid can be reused after a |
| 129 | // process dies, it is useful to use both the Pid and the creation time to |
| 130 | // uniquely identify a process. |
| 131 | // |
Benoit Lize | 8a54469 | 2020-08-31 15:43:42 | [diff] [blame] | 132 | // On Android, works only if |this| is the current process, as security |
| 133 | // features prevent an application from getting data about other processes, |
| 134 | // even if they belong to us. Otherwise, returns Time(). |
Francois Doray | 7d131534 | 2018-10-21 03:54:47 | [diff] [blame] | 135 | Time CreationTime() const; |
Francois Doray | 7d131534 | 2018-10-21 03:54:47 | [diff] [blame] | 136 | |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 137 | // Returns true if this process is the current process. |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 138 | bool is_current() const; |
| 139 | |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 140 | #if BUILDFLAG(IS_CHROMEOS) |
| 141 | // A unique token generated for each process, this is used to create a unique |
| 142 | // cgroup for each renderer. |
| 143 | const std::string& unique_token() const { return unique_token_; } |
| 144 | #endif |
| 145 | |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 146 | // Close the process handle. This will not terminate the process. |
| 147 | void Close(); |
| 148 | |
Zijie He | 4dd88ae42 | 2017-09-20 01:30:18 | [diff] [blame] | 149 | // Returns true if this process is still running. This is only safe on Windows |
| 150 | // (and maybe Fuchsia?), because the ProcessHandle will keep the zombie |
| 151 | // process information available until itself has been released. But on Posix, |
| 152 | // the OS may reuse the ProcessId. |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 153 | #if BUILDFLAG(IS_WIN) |
Zijie He | 4dd88ae42 | 2017-09-20 01:30:18 | [diff] [blame] | 154 | bool IsRunning() const { |
| 155 | return !WaitForExitWithTimeout(base::TimeDelta(), nullptr); |
| 156 | } |
| 157 | #endif |
| 158 | |
rvargas | 02ad783 | 2015-04-02 01:36:06 | [diff] [blame] | 159 | // Terminates the process with extreme prejudice. The given |exit_code| will |
rvargas | eedb763e | 2015-03-09 23:53:45 | [diff] [blame] | 160 | // be the exit code of the process. If |wait| is true, this method will wait |
| 161 | // for up to one minute for the process to actually terminate. |
| 162 | // Returns true if the process terminates within the allowed time. |
Johann | 30f9447 | 2021-04-07 23:54:24 | [diff] [blame] | 163 | // NOTE: |exit_code| is only used on OS_WIN. |
rvargas | 02ad783 | 2015-04-02 01:36:06 | [diff] [blame] | 164 | bool Terminate(int exit_code, bool wait) const; |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 165 | |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 166 | #if BUILDFLAG(IS_WIN) |
Mike Rorke | f36971b | 2020-03-06 17:56:29 | [diff] [blame] | 167 | enum class WaitExitStatus { |
| 168 | PROCESS_EXITED, |
| 169 | STOP_EVENT_SIGNALED, |
| 170 | FAILED, |
| 171 | }; |
| 172 | |
| 173 | // Waits for the process to exit, or the specified |stop_event_handle| to be |
| 174 | // set. Returns value indicating which event was set. The given |exit_code| |
| 175 | // will be the exit code of the process. |
| 176 | WaitExitStatus WaitForExitOrEvent( |
| 177 | const base::win::ScopedHandle& stop_event_handle, |
| 178 | int* exit_code) const; |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 179 | #endif // BUILDFLAG(IS_WIN) |
Mike Rorke | f36971b | 2020-03-06 17:56:29 | [diff] [blame] | 180 | |
rvargas | 126fd582 | 2014-12-12 00:25:14 | [diff] [blame] | 181 | // Waits for the process to exit. Returns true on success. |
| 182 | // On POSIX, if the process has been signaled then |exit_code| is set to -1. |
rvargas | 2f70a15 | 2015-02-24 00:28:11 | [diff] [blame] | 183 | // On Linux this must be a child process, however on Mac and Windows it can be |
| 184 | // any process. |
g.mehndiratt | fd19e23 | 2015-05-29 08:17:14 | [diff] [blame] | 185 | // NOTE: |exit_code| is optional, nullptr can be passed if the exit code is |
| 186 | // not required. |
jcivelli | f4462a35 | 2017-01-10 04:45:59 | [diff] [blame] | 187 | bool WaitForExit(int* exit_code) const; |
rvargas | 126fd582 | 2014-12-12 00:25:14 | [diff] [blame] | 188 | |
| 189 | // Same as WaitForExit() but only waits for up to |timeout|. |
g.mehndiratt | fd19e23 | 2015-05-29 08:17:14 | [diff] [blame] | 190 | // NOTE: |exit_code| is optional, nullptr can be passed if the exit code |
| 191 | // is not required. |
jcivelli | f4462a35 | 2017-01-10 04:45:59 | [diff] [blame] | 192 | bool WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) const; |
rvargas | 126fd582 | 2014-12-12 00:25:14 | [diff] [blame] | 193 | |
Brian White | ae2a8b9a | 2017-11-02 19:10:36 | [diff] [blame] | 194 | // Indicates that the process has exited with the specified |exit_code|. |
| 195 | // This should be called if process exit is observed outside of this class. |
| 196 | // (i.e. Not because Terminate or WaitForExit, above, was called.) |
| 197 | // Note that nothing prevents this being called multiple times for a dead |
| 198 | // process though that should be avoided. |
| 199 | void Exited(int exit_code) const; |
| 200 | |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 201 | // The different priorities that a process can have. |
| 202 | // TODO(pmonette): Consider merging with base::TaskPriority when the API is |
| 203 | // stable. |
| 204 | enum class Priority { |
| 205 | // The process does not contribute to content that is currently important |
| 206 | // to the user. Lowest priority. |
| 207 | kBestEffort, |
| 208 | |
Zheda Chen | e7421f3 | 2024-08-29 03:05:39 | [diff] [blame^] | 209 | // The process contributes to content that is visible to the user, but the |
| 210 | // work don't have significant performance or latency requirement, so it can |
| 211 | // run in energy efficient manner. Moderate priority. |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 212 | kUserVisible, |
| 213 | |
| 214 | // The process contributes to content that is of the utmost importance to |
| 215 | // the user, like producing audible content, or visible content in the |
Zheda Chen | e7421f3 | 2024-08-29 03:05:39 | [diff] [blame^] | 216 | // main frame. High priority. |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 217 | kUserBlocking, |
| 218 | }; |
| 219 | |
Dave Tapuska | ed322d0 | 2023-03-07 23:33:33 | [diff] [blame] | 220 | #if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && BUILDFLAG(USE_BLINK)) |
lgrey | 0d2bafc | 2016-11-07 16:28:33 | [diff] [blame] | 221 | // The Mac needs a Mach port in order to manipulate a process's priority, |
| 222 | // and there's no good way to get that from base given the pid. These Mac |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 223 | // variants of the `GetPriority()` and `SetPriority()` API take a port |
| 224 | // provider for this reason. See crbug.com/460102. |
lgrey | 0d2bafc | 2016-11-07 16:28:33 | [diff] [blame] | 225 | |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 226 | // Retrieves the priority of the process. Defaults to Priority::kUserBlocking |
| 227 | // if the priority could not be retrieved, or if `port_provider` is null. |
| 228 | Priority GetPriority(PortProvider* port_provider) const; |
| 229 | |
| 230 | // Sets the priority of the process process. Returns true if the priority was |
| 231 | // changed, false otherwise. If `port_provider` is null, this is a no-op and |
| 232 | // it returns false. |
| 233 | bool SetPriority(PortProvider* port_provider, Priority priority); |
lgrey | 0d2bafc | 2016-11-07 16:28:33 | [diff] [blame] | 234 | #else |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 235 | // Retrieves the priority of the process. Defaults to Priority::kUserBlocking |
| 236 | // if the priority could not be retrieved. |
| 237 | Priority GetPriority() const; |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 238 | |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 239 | // Sets the priority of the process process. Returns true if the priority was |
| 240 | // changed, false otherwise. |
| 241 | bool SetPriority(Priority priority); |
Dave Tapuska | ed322d0 | 2023-03-07 23:33:33 | [diff] [blame] | 242 | #endif // BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && BUILDFLAG(USE_BLINK)) |
| 243 | |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 244 | // Returns an integer representing the priority of a process. The meaning |
| 245 | // of this value is OS dependent. |
Patrick Monette | 740b81b | 2023-07-21 21:09:09 | [diff] [blame] | 246 | int GetOSPriority() const; |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 247 | |
Yuta Hijikata | 000df18f | 2020-11-18 06:55:58 | [diff] [blame] | 248 | #if BUILDFLAG(IS_CHROMEOS_ASH) |
nya | d2c548b | 2015-12-09 03:22:32 | [diff] [blame] | 249 | // Get the PID in its PID namespace. |
| 250 | // If the process is not in a PID namespace or /proc/<pid>/status does not |
| 251 | // report NSpid, kNullProcessId is returned. |
| 252 | ProcessId GetPidInNamespace() const; |
| 253 | #endif |
| 254 | |
Matthew Denton | f96988342 | 2023-08-08 01:44:34 | [diff] [blame] | 255 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| 256 | // Returns true if the process has any seccomp policy applied. |
| 257 | bool IsSeccompSandboxed(); |
| 258 | #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| 259 | |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 260 | #if BUILDFLAG(IS_CHROMEOS) |
Shintaro Kawamura | f29c8fdf | 2024-03-28 03:40:08 | [diff] [blame] | 261 | // Sets a delegate which handles process priority changes. This |
| 262 | // must be externally synchronized with any call to base::Process methods. |
| 263 | static void SetProcessPriorityDelegate(ProcessPriorityDelegate* delegate); |
| 264 | |
Youssef Esmat | 10aa75d | 2022-06-10 11:58:46 | [diff] [blame] | 265 | // Exposes OneGroupPerRendererEnabled() to unit tests. |
| 266 | static bool OneGroupPerRendererEnabledForTesting(); |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 267 | |
| 268 | // If OneGroupPerRenderer is enabled, runs at process startup to clean up |
| 269 | // any stale cgroups that were left behind from any unclean exits of the |
| 270 | // browser process. |
| 271 | static void CleanUpStaleProcessStates(); |
| 272 | |
Shintaro Kawamura | f726c129 | 2024-03-28 03:40:08 | [diff] [blame] | 273 | // Initializes the process's priority. |
| 274 | // |
| 275 | // This should be called before SetPriority(). |
| 276 | // |
| 277 | // If SchedQoSOnResourcedForChrome is enabled, this creates a cache entry for |
| 278 | // the process priority. The returned `base::Process::PriorityEntry` should be |
| 279 | // freed when the process is terminated so that the cached entry is freed from |
| 280 | // the internal map. |
| 281 | // |
| 282 | // If OneGroupPerRenderer is enabled, it also creates a unique cgroup for the |
| 283 | // process. |
| 284 | // This is a no-op if the Process is not valid or if it has already been |
| 285 | // called. |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 286 | void InitializePriority(); |
Shintaro Kawamura | f726c129 | 2024-03-28 03:40:08 | [diff] [blame] | 287 | |
| 288 | // Clears the entities initialized by InitializePriority(). |
| 289 | // |
| 290 | // This is no-op if SchedQoSOnResourcedForChrome is disabled. |
| 291 | void ForgetPriority(); |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 292 | #endif // BUILDFLAG(IS_CHROMEOS) |
| 293 | |
Dave Tapuska | ed322d0 | 2023-03-07 23:33:33 | [diff] [blame] | 294 | #if BUILDFLAG(IS_APPLE) |
Patrick Monette | 209f31da | 2023-08-31 21:25:33 | [diff] [blame] | 295 | // Sets the priority of the current process to its default value. |
Patrick Monette | ee7f72f | 2023-01-23 22:59:45 | [diff] [blame] | 296 | static void SetCurrentTaskDefaultRole(); |
| 297 | #endif // BUILDFLAG(IS_MAC) |
| 298 | |
Dave Tapuska | 31c385c | 2024-04-12 18:43:11 | [diff] [blame] | 299 | #if BUILDFLAG(IS_IOS) && BUILDFLAG(USE_BLINK) |
| 300 | using TerminateCallback = bool (*)(ProcessHandle handle); |
| 301 | using WaitForExitCallback = bool (*)(ProcessHandle handle, |
| 302 | int* exit_code, |
| 303 | base::TimeDelta timeout); |
| 304 | // Function ptrs to implement termination without polluting //base with |
| 305 | // BrowserEngineKit APIs. |
| 306 | static void SetTerminationHooks(TerminateCallback terminate_callback, |
| 307 | WaitForExitCallback wait_callback); |
| 308 | #if TARGET_OS_SIMULATOR |
| 309 | // Methods for supporting both "content processes" and traditional |
| 310 | // forked processes. For non-simulator builds on iOS every process would |
| 311 | // be a "content process" so we don't need the conditionals. |
| 312 | void SetIsContentProcess(); |
| 313 | bool IsContentProcess() const; |
| 314 | #endif |
| 315 | #endif |
| 316 | |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 317 | private: |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 318 | #if BUILDFLAG(IS_CHROMEOS) |
| 319 | // Cleans up process state. If OneGroupPerRenderer is enabled, it cleans up |
| 320 | // the cgroup created by InitializePriority(). If the process has not |
| 321 | // fully terminated yet, it will post a background task to try again. |
| 322 | void CleanUpProcess(int remaining_retries) const; |
| 323 | |
| 324 | // Calls CleanUpProcess() on a background thread. |
| 325 | void CleanUpProcessAsync() const; |
| 326 | |
| 327 | // Used to call CleanUpProcess() on a background thread because Process is not |
| 328 | // refcounted. |
| 329 | static void CleanUpProcessScheduled(Process process, int remaining_retries); |
| 330 | #endif // BUILDFLAG(IS_CHROMEOS) |
| 331 | |
Dave Tapuska | 31c385c | 2024-04-12 18:43:11 | [diff] [blame] | 332 | #if !BUILDFLAG(IS_IOS) || (BUILDFLAG(IS_IOS) && TARGET_OS_SIMULATOR) |
| 333 | bool TerminateInternal(int exit_code, bool wait) const; |
| 334 | bool WaitForExitWithTimeoutImpl(base::ProcessHandle handle, |
| 335 | int* exit_code, |
| 336 | base::TimeDelta timeout) const; |
| 337 | #endif |
| 338 | |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 339 | #if BUILDFLAG(IS_WIN) |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 340 | win::ScopedHandle process_; |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 341 | #elif BUILDFLAG(IS_FUCHSIA) |
Wez | 157707d6 | 2018-07-10 22:48:47 | [diff] [blame] | 342 | zx::process process_; |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 343 | #else |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 344 | ProcessHandle process_; |
rvargas | 079d184 | 2014-10-17 22:32:16 | [diff] [blame] | 345 | #endif |
dcheng | 1a2fd6cd | 2016-06-07 21:39:12 | [diff] [blame] | 346 | |
Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 347 | #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA) |
scottmg | 297cc93 | 2017-05-24 03:45:58 | [diff] [blame] | 348 | bool is_current_process_; |
| 349 | #endif |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 350 | |
Dave Tapuska | 31c385c | 2024-04-12 18:43:11 | [diff] [blame] | 351 | #if BUILDFLAG(IS_IOS) && BUILDFLAG(USE_BLINK) && TARGET_OS_SIMULATOR |
| 352 | // A flag indicating that this is a "content process". iOS does not support |
| 353 | // generic process invocation but it does support some types of well defined |
| 354 | // processes. These types of processes are defined at the //content layer so |
| 355 | // for termination we defer to some globally initialized callbacks. |
| 356 | bool content_process_ = false; |
| 357 | #endif |
| 358 | |
Youssef Esmat | c732bf8 | 2022-05-27 00:47:19 | [diff] [blame] | 359 | #if BUILDFLAG(IS_CHROMEOS) |
| 360 | // A unique token per process not per class instance (`base::Process`). This |
| 361 | // is similar to the PID of a process but should not be reused after the |
| 362 | // process's termination. The token will be copied during Duplicate() |
| 363 | // and move semantics as is the PID/ProcessHandle. |
| 364 | std::string unique_token_; |
| 365 | #endif |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 366 | }; |
| 367 | |
Eric Willigers | 611cf54 | 2022-04-28 02:22:14 | [diff] [blame] | 368 | #if BUILDFLAG(IS_CHROMEOS) |
afakhry | 8b4796b | 2015-11-16 18:41:44 | [diff] [blame] | 369 | // Exposed for testing. |
| 370 | // Given the contents of the /proc/<pid>/cgroup file, determine whether the |
| 371 | // process is backgrounded or not. |
Patrick Monette | 5d1ba7ca | 2023-08-02 22:05:27 | [diff] [blame] | 372 | BASE_EXPORT Process::Priority GetProcessPriorityCGroup( |
Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 373 | std::string_view cgroup_contents); |
Eric Willigers | 611cf54 | 2022-04-28 02:22:14 | [diff] [blame] | 374 | #endif // BUILDFLAG(IS_CHROMEOS) |
afakhry | 8b4796b | 2015-11-16 18:41:44 | [diff] [blame] | 375 | |
[email protected] | 76bea67 | 2013-07-19 16:48:56 | [diff] [blame] | 376 | } // namespace base |
| 377 | |
danakj | 0a44860 | 2015-03-10 00:31:16 | [diff] [blame] | 378 | #endif // BASE_PROCESS_PROCESS_H_ |