blob: f3d9c3ac9b65593bba09cb84a592d72e3f3dfdd0 [file] [log] [blame]
Dave Tapuska31c385c2024-04-12 18:43:111// Copyright 2024 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#include "base/process/process.h"
6
S. Ganeshe4a99862025-04-29 03:30:457#include <algorithm>
8
Dave Tapuska31c385c2024-04-12 18:43:119#include "base/threading/thread_restrictions.h"
10
11namespace base {
12
13namespace {
14
15static Process::TerminateCallback g_terminate_callback = nullptr;
16static Process::WaitForExitCallback g_wait_for_exit_callback = nullptr;
17
18} // namespace
19
20bool WaitForExitWithTimeoutImpl(base::ProcessHandle handle,
21 int* exit_code,
22 base::TimeDelta timeout);
23
24void Process::SetTerminationHooks(TerminateCallback terminate_callback,
25 WaitForExitCallback wait_callback) {
26 CHECK(!g_terminate_callback);
27 CHECK(!g_wait_for_exit_callback);
28 g_terminate_callback = terminate_callback;
29 g_wait_for_exit_callback = wait_callback;
30}
31
32#if TARGET_OS_SIMULATOR
33void Process::SetIsContentProcess() {
34 content_process_ = true;
35}
36
37bool Process::IsContentProcess() const {
38 return content_process_;
39}
40#endif
41
42bool Process::Terminate(int exit_code, bool wait) const {
43 // exit_code isn't supportable.
44 DCHECK(IsValid());
45 CHECK_GT(process_, 0);
46#if TARGET_OS_SIMULATOR
47 if (!content_process_) {
48 return TerminateInternal(exit_code, wait);
49 }
50#endif
51 CHECK(g_terminate_callback);
Dave Tapuskab7422332025-05-22 22:10:3952 return (*g_terminate_callback)(process_, exit_code, wait);
Dave Tapuska31c385c2024-04-12 18:43:1153}
54
55bool Process::WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) const {
S. Ganeshe4a99862025-04-29 03:30:4556 timeout = std::max(timeout, TimeDelta());
Dave Tapuska31c385c2024-04-12 18:43:1157 if (!timeout.is_zero()) {
58 // Assert that this thread is allowed to wait below. This intentionally
59 // doesn't use ScopedBlockingCallWithBaseSyncPrimitives because the process
60 // being waited upon tends to itself be using the CPU and considering this
61 // thread non-busy causes more issue than it fixes: http://crbug.com/905788
62 internal::AssertBaseSyncPrimitivesAllowed();
63 }
64
65#if TARGET_OS_SIMULATOR
66 if (!content_process_) {
67 return WaitForExitWithTimeoutImpl(Handle(), exit_code, timeout);
68 }
69#endif
70 return (*g_wait_for_exit_callback)(process_, exit_code, timeout);
71}
72
73} // namespace base