Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: content/browser/child_process_launcher.h

Issue 2594203004: Unifying ChildProcessLauncher across platforms. (Closed)
Patch Set: Addressed boliu@'s comments Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_ 5 #ifndef CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_
6 #define CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_ 6 #define CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_
7 7
8 #include "base/files/scoped_file.h" 8 #include <memory>
9
9 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h"
10 #include "base/memory/shared_memory.h" 12 #include "base/memory/shared_memory.h"
11 #include "base/memory/weak_ptr.h" 13 #include "base/memory/weak_ptr.h"
12 #include "base/process/kill.h" 14 #include "base/process/kill.h"
13 #include "base/process/launch.h"
14 #include "base/process/process.h" 15 #include "base/process/process.h"
15 #include "base/threading/non_thread_safe.h" 16 #include "base/threading/non_thread_safe.h"
16 #include "build/build_config.h" 17 #include "build/build_config.h"
17 #include "content/common/content_export.h" 18 #include "content/common/content_export.h"
18 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
19 #include "content/public/common/sandboxed_process_launcher_delegate.h" 20 #include "content/public/common/result_codes.h"
21 #include "content/public/common/zygote_handle.h"
20 #include "mojo/edk/embedder/embedder.h" 22 #include "mojo/edk/embedder/embedder.h"
21 #include "mojo/edk/embedder/scoped_platform_handle.h" 23 #include "mojo/edk/embedder/scoped_platform_handle.h"
22 24
23 #if defined(OS_WIN) 25 #if defined(OS_WIN)
24 #include "sandbox/win/src/sandbox_types.h" 26 #include "sandbox/win/src/sandbox_types.h"
27 #else
28 #include "content/public/browser/file_descriptor_info.h"
25 #endif 29 #endif
26 30
27 namespace base { 31 namespace base {
28 class CommandLine; 32 class CommandLine;
29 } 33 }
30 34
31 namespace content { 35 namespace content {
32 36
37 class SandboxedProcessLauncherDelegate;
38
39 #if defined(OS_WIN)
40 using FileMappedForLaunch = base::HandlesToInheritVector ;
jam 2017/01/13 18:42:20 nit: space at end
Jay Civelli 2017/01/17 17:50:03 Done.
41 #else
42 class FileDescriptorInfo;
43 using FileMappedForLaunch = FileDescriptorInfo;
44 #endif
45
33 // Note: These codes are listed in a histogram and any new codes should be added 46 // Note: These codes are listed in a histogram and any new codes should be added
34 // at the end. 47 // at the end.
35 enum LaunchResultCode { 48 enum LaunchResultCode {
36 // Launch start code, to not overlap with sandbox::ResultCode. 49 // Launch start code, to not overlap with sandbox::ResultCode.
37 LAUNCH_RESULT_START = 1001, 50 LAUNCH_RESULT_START = 1001,
38 // Launch success. 51 // Launch success.
39 LAUNCH_RESULT_SUCCESS, 52 LAUNCH_RESULT_SUCCESS,
40 // Generic launch failure. 53 // Generic launch failure.
41 LAUNCH_RESULT_FAILURE, 54 LAUNCH_RESULT_FAILURE,
42 // Placeholder for last item of the enum. 55 // Placeholder for last item of the enum.
(...skipping 16 matching lines...) Expand all
59 // Will be called on the thread that the ChildProcessLauncher was 72 // Will be called on the thread that the ChildProcessLauncher was
60 // constructed on. 73 // constructed on.
61 virtual void OnProcessLaunched() = 0; 74 virtual void OnProcessLaunched() = 0;
62 75
63 virtual void OnProcessLaunchFailed(int error_code) {}; 76 virtual void OnProcessLaunchFailed(int error_code) {};
64 77
65 protected: 78 protected:
66 virtual ~Client() {} 79 virtual ~Client() {}
67 }; 80 };
68 81
82 // The Helper class provides the platform specific implementation of the child
jam 2017/01/13 18:42:19 nit: can we put this in the end of the public sect
Jay Civelli 2017/01/17 17:50:03 Moved to a new child_process_launcher_helper file.
83 // process launching and decouples the lifecycle of ChildProcessLauncher from
84 // the process launch itself (and the task posting it involves) so that
85 // ChildProcessLauncher can be deleted at any point.
86 class Helper : public base::RefCountedThreadSafe<Helper> {
jam 2017/01/13 18:42:19 hmm, implementation inheritance is something I've
Jay Civelli 2017/01/17 17:50:03 From our discussion, there is no inheritance, the
87 public:
88 Helper(int child_process_id,
89 BrowserThread::ID client_thread_id,
90 std::unique_ptr<base::CommandLine> command_line,
91 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
92 const base::WeakPtr<ChildProcessLauncher>& child_process_launcher,
93 bool terminate_on_shutdown);
94
95 // The methods below are defined in the order they are called.
96
97 // Starts the flow of launching the process.
98 void StartLaunchOnClientThread();
99
100 // Platform specific.
101 void BeforeLaunchOnClientThread();
102
103 // Called in to give implementors a chance at creating a server pipe.
104 // Platform specific.
105 mojo::edk::ScopedPlatformHandle PrepareMojoPipeHandlesOnClientThread();
106
107 // Returns the list of files that should be mapped in the child process.
108 // Platform specific.
109 std::unique_ptr<FileMappedForLaunch> GetFilesToMap();
110
111 // Should return true when a zygote should be used, in which case
112 // ForkAsZygote() will be called (so far Linux only).
113 // Platform specific.
114 bool ShouldForkAsZygote();
jam 2017/01/13 18:42:19 why not add ifdefs here to make it clear these met
Jay Civelli 2017/01/17 17:50:03 I created a custom CLP Process struct that contain
115
116 // Starts the child as a zygote.
117 // Platform specific.
118 ZygoteHandle ForkAsZygote(
119 std::unique_ptr<FileMappedForLaunch> files_to_register,
120 base::Process* process);
121
122 // Platform specific.
123 void BeforeLaunchOnLauncherThread(
124 const FileMappedForLaunch& files_to_register,
125 base::LaunchOptions* options);
126
127 // Does the actual starting of the process.
128 // |is_synchronous_launch| is set to true if the starting of the process is
129 // asynchonous (this is the case on Android), in which case the retuned
130 // Process is not valid (and PostLaunchOnLauncherThread() will provide the
131 // process once it is available).
132 // Platform specific.
133 base::Process LaunchProcessOnLauncherThread(
134 const base::LaunchOptions& options,
135 FileMappedForLaunch* files_to_register,
136 bool* is_synchronous_launch,
137 int* launch_result);
138
139 // Called right after the process has been launched, whether it was created
140 // yet or not.
141 // Platform specific.
142 void AfterLaunchOnLauncherThread(const base::Process& process,
143 const base::LaunchOptions& options);
144
145 // Called once the process has been created with a valid |process| if the
146 // process wasn't started successfully.
147 // if |post_launch_on_client_thread_called| is false,
148 // PostLaunchOnClientThread is called on the client thread.
149 void PostLaunchOnLauncherThread(
150 base::Process process,
151 ZygoteHandle zygote,
152 int launch_result,
153 bool post_launch_on_client_thread_called);
154
155 // Note that this could be called before PostLaunchOnLauncherThread() is
156 // called.
157 void PostLaunchOnClientThread(base::Process process,
158 ZygoteHandle zygote,
159 int error_code);
160
161 int client_thread_id() const { return client_thread_id_; }
162
163 protected:
164 virtual ~Helper();
165
166 private:
167 friend class base::RefCountedThreadSafe<Helper>;
168
169 void LaunchOnLauncherThread();
170
171 const mojo::edk::PlatformHandle& mojo_client_handle() const {
172 return mojo_client_handle_.get();
173 }
174 base::CommandLine* command_line() { return command_line_.get(); }
175 int child_process_id() const { return child_process_id_; }
176
177 std::string GetProcessType();
178
179 const int child_process_id_;
180 const BrowserThread::ID client_thread_id_;
181 base::TimeTicks begin_launch_time_;
182 std::unique_ptr<base::CommandLine> command_line_;
183 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate_;
184 base::WeakPtr<ChildProcessLauncher> child_process_launcher_;
185 mojo::edk::ScopedPlatformHandle mojo_client_handle_;
186 mojo::edk::ScopedPlatformHandle mojo_server_handle_;
187 bool terminate_on_shutdown_;
188 };
189
69 // Launches the process asynchronously, calling the client when the result is 190 // Launches the process asynchronously, calling the client when the result is
70 // ready. Deleting this object before the process is created is safe, since 191 // ready. Deleting this object before the process is created is safe, since
71 // the callback won't be called. If the process is still running by the time 192 // the callback won't be called. If the process is still running by the time
72 // this object destructs, it will be terminated. 193 // this object destructs, it will be terminated.
73 // Takes ownership of cmd_line. 194 // Takes ownership of cmd_line.
74 // 195 //
75 // If |process_error_callback| is provided, it will be called if a Mojo error 196 // If |process_error_callback| is provided, it will be called if a Mojo error
76 // is encountered when processing messages from the child process. This 197 // is encountered when processing messages from the child process. This
77 // callback must be safe to call from any thread. 198 // callback must be safe to call from any thread.
78 ChildProcessLauncher( 199 ChildProcessLauncher(
(...skipping 23 matching lines...) Expand all
102 // |exit_code| is the exit code of the process if it exited (e.g. status from 223 // |exit_code| is the exit code of the process if it exited (e.g. status from
103 // waitpid if on posix, from GetExitCodeProcess on Windows). |exit_code| may 224 // waitpid if on posix, from GetExitCodeProcess on Windows). |exit_code| may
104 // be NULL. 225 // be NULL.
105 base::TerminationStatus GetChildTerminationStatus(bool known_dead, 226 base::TerminationStatus GetChildTerminationStatus(bool known_dead,
106 int* exit_code); 227 int* exit_code);
107 228
108 // Changes whether the process runs in the background or not. Only call 229 // Changes whether the process runs in the background or not. Only call
109 // this after the process has started. 230 // this after the process has started.
110 void SetProcessBackgrounded(bool background); 231 void SetProcessBackgrounded(bool background);
111 232
233 // Terminates the process.
234 // Returns true if the process was stopped, false if the process had not been
235 // started yet or could not be stopped.
236 // Note that |exit_code| and |wait| are not used on Android.
237 bool Terminate(int exit_code, bool wait);
238
239 // Similar to Terminate() but takes in a |process|, expected to have been
240 // started by ChildProcessLauncher.
241 static bool TerminateProcess(const base::Process& process,
242 int exit_code,
243 bool wait);
244
112 // Replaces the ChildProcessLauncher::Client for testing purposes. Returns the 245 // Replaces the ChildProcessLauncher::Client for testing purposes. Returns the
113 // previous client. 246 // previous client.
114 Client* ReplaceClientForTest(Client* client); 247 Client* ReplaceClientForTest(Client* client);
115 248
116 private: 249 private:
117 // Posts a task to the launcher thread to do the actual work. 250 static void Terminate(ZygoteHandle zygote, base::Process process);
118 void Launch(std::unique_ptr<SandboxedProcessLauncherDelegate> delegate, 251 static void TerminateOnLauncherThread(
119 std::unique_ptr<base::CommandLine> cmd_line, 252 ZygoteHandle zygote, base::Process process);
120 int child_process_id); 253 static void SetProcessBackgroundedOnLauncherThread(
254 base::Process process, bool background);
121 255
122 void UpdateTerminationStatus(bool known_dead); 256 void UpdateTerminationStatus(bool known_dead);
123 257
124 // This is always called on the client thread after an attempt
125 // to launch the child process on the launcher thread.
126 // It makes sure we always perform the necessary cleanup if the
127 // client went away.
128 static void DidLaunch(base::WeakPtr<ChildProcessLauncher> instance,
129 bool terminate_on_shutdown,
130 mojo::edk::ScopedPlatformHandle server_handle,
131 ZygoteHandle zygote,
132 #if defined(OS_ANDROID)
133 base::ScopedFD mojo_fd,
134 #endif
135 base::Process process,
136 int error_code);
137
138 // Notifies the client about the result of the operation. 258 // Notifies the client about the result of the operation.
139 void Notify(ZygoteHandle zygote, 259 void Notify(ZygoteHandle zygote,
140 mojo::edk::ScopedPlatformHandle server_handle, 260 mojo::edk::ScopedPlatformHandle server_handle,
141 base::Process process, 261 base::Process process,
142 int error_code); 262 int error_code);
143 263
144 Client* client_; 264 Client* client_;
145 BrowserThread::ID client_thread_id_; 265 BrowserThread::ID client_thread_id_;
146 base::Process process_; 266 base::Process process_;
147 base::TerminationStatus termination_status_; 267 base::TerminationStatus termination_status_;
148 int exit_code_; 268 int exit_code_;
149 ZygoteHandle zygote_; 269 ZygoteHandle zygote_;
150 bool starting_; 270 bool starting_;
151 const mojo::edk::ProcessErrorCallback process_error_callback_; 271 const mojo::edk::ProcessErrorCallback process_error_callback_;
152 272
153 // Controls whether the child process should be terminated on browser 273 // Controls whether the child process should be terminated on browser
154 // shutdown. Default behavior is to terminate the child. 274 // shutdown. Default behavior is to terminate the child.
155 const bool terminate_child_on_shutdown_; 275 const bool terminate_child_on_shutdown_;
156 276
157 const std::string mojo_child_token_; 277 const std::string mojo_child_token_;
158 278
279 scoped_refptr<Helper> helper_;
280
159 base::WeakPtrFactory<ChildProcessLauncher> weak_factory_; 281 base::WeakPtrFactory<ChildProcessLauncher> weak_factory_;
160 282
161 DISALLOW_COPY_AND_ASSIGN(ChildProcessLauncher); 283 DISALLOW_COPY_AND_ASSIGN(ChildProcessLauncher);
162 }; 284 };
163 285
164 } // namespace content 286 } // namespace content
165 287
166 #endif // CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_ 288 #endif // CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698