Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |