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 typedef base::HandlesToInheritVector FileMappedForLaunch; | |
|
boliu
2017/01/12 02:00:07
nit: prefer c++11 alias
Jay Civelli
2017/01/12 23:05:41
Done.
| |
| 41 #else | |
| 42 class FileDescriptorInfo; | |
| 43 typedef FileDescriptorInfo FileMappedForLaunch; | |
| 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 class Helper : public base::RefCountedThreadSafe<Helper> { | |
|
boliu
2017/01/12 02:00:07
maybe add a comment that helper is the platform-sp
Jay Civelli
2017/01/12 23:05:41
Added a comment.
| |
| 83 public: | |
| 84 Helper(int child_process_id, | |
| 85 BrowserThread::ID client_thread_id, | |
| 86 std::unique_ptr<base::CommandLine> command_line, | |
| 87 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate, | |
| 88 const base::WeakPtr<ChildProcessLauncher>& child_process_launcher, | |
| 89 bool terminate_on_shutdown); | |
| 90 | |
| 91 void BeforeLaunchOnClientThread(); | |
|
boliu
2017/01/12 02:00:07
group methods that are *actually* implemented by p
Jay Civelli
2017/01/12 23:05:41
I like to have them in the order they are invoked,
| |
| 92 | |
| 93 // Called in to give implementors a chance at creating a server pipe. | |
| 94 mojo::edk::ScopedPlatformHandle PrepareMojoPipeHandlesOnClientThread(); | |
| 95 | |
| 96 // Posts a task to the launcher thread to do the actual work. | |
| 97 void LaunchOnClientThread(); | |
| 98 | |
| 99 // Returns the list of files that should be mapped in the child process. | |
| 100 std::unique_ptr<FileMappedForLaunch> GetFilesToMap(); | |
| 101 | |
| 102 // Should return true when a zygote should be used, in which case | |
| 103 // ForkAsZygote() will be called (so far Linux only). | |
| 104 bool ShouldForkAsZygote(); | |
|
boliu
2017/01/12 02:00:07
just curious.. and I didn't read all platforms, bu
Jay Civelli
2017/01/12 23:05:41
It depends on command line provided flags on Linux
| |
| 105 | |
| 106 // Starts the child as a zygote. | |
| 107 ZygoteHandle ForkAsZygote( | |
| 108 std::unique_ptr<FileMappedForLaunch> files_to_register, | |
| 109 base::Process* process); | |
| 110 | |
| 111 void BeforeLaunchOnLauncherThread( | |
| 112 const FileMappedForLaunch& files_to_register, | |
| 113 base::LaunchOptions* options); | |
| 114 | |
| 115 // Does the actual starting of the process. | |
| 116 // |is_synchronous_launch| is set to true if the starting of the process is | |
| 117 // asynchonous (this is the case on Android), in which case the retuned | |
| 118 // Process is not valid (and PostLaunchOnLauncherThread() will provide the | |
| 119 // process once it is available). | |
| 120 base::Process LaunchProcessOnLauncherThread( | |
| 121 const base::LaunchOptions& options, | |
| 122 FileMappedForLaunch* files_to_register, | |
| 123 bool* is_synchronous_launch, | |
| 124 int* launch_result); | |
| 125 | |
| 126 // Called right after the process has been launched, whether it was created | |
| 127 // yet or not. | |
| 128 void AfterLaunchOnLauncherThread(const base::Process& process, | |
| 129 const base::LaunchOptions& options); | |
| 130 | |
| 131 // Called once the process has been created with a valid |process| if the | |
| 132 // process wasn't started successfully. | |
| 133 void PostLaunchOnLauncherThread( | |
| 134 base::Process process, ZygoteHandle zygote, int launch_result); | |
| 135 | |
| 136 void PostLaunchOnClientThread(base::Process process, | |
| 137 ZygoteHandle zygote, | |
| 138 int error_code); | |
| 139 | |
| 140 protected: | |
| 141 virtual ~Helper(); | |
| 142 | |
| 143 private: | |
| 144 friend class base::RefCountedThreadSafe<Helper>; | |
| 145 | |
| 146 void LaunchOnLauncherThread(); | |
| 147 | |
| 148 const mojo::edk::PlatformHandle& mojo_client_handle() const { | |
| 149 return mojo_client_handle_.get(); | |
| 150 } | |
| 151 base::CommandLine* command_line() { return command_line_.get(); } | |
| 152 int child_process_id() const { return child_process_id_; } | |
| 153 | |
| 154 std::string GetProcessType(); | |
| 155 | |
| 156 const int child_process_id_; | |
| 157 const BrowserThread::ID client_thread_id_; | |
| 158 base::TimeTicks begin_launch_time_; | |
| 159 std::unique_ptr<base::CommandLine> command_line_; | |
| 160 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate_; | |
| 161 base::WeakPtr<ChildProcessLauncher> child_process_launcher_; | |
| 162 mojo::edk::ScopedPlatformHandle mojo_client_handle_; | |
| 163 mojo::edk::ScopedPlatformHandle mojo_server_handle_; | |
| 164 bool terminate_on_shutdown_; | |
| 165 }; | |
| 166 | |
| 69 // Launches the process asynchronously, calling the client when the result is | 167 // Launches the process asynchronously, calling the client when the result is |
| 70 // ready. Deleting this object before the process is created is safe, since | 168 // 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 | 169 // the callback won't be called. If the process is still running by the time |
| 72 // this object destructs, it will be terminated. | 170 // this object destructs, it will be terminated. |
| 73 // Takes ownership of cmd_line. | 171 // Takes ownership of cmd_line. |
| 74 // | 172 // |
| 75 // If |process_error_callback| is provided, it will be called if a Mojo error | 173 // 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 | 174 // is encountered when processing messages from the child process. This |
| 77 // callback must be safe to call from any thread. | 175 // callback must be safe to call from any thread. |
| 78 ChildProcessLauncher( | 176 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 | 200 // |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 | 201 // waitpid if on posix, from GetExitCodeProcess on Windows). |exit_code| may |
| 104 // be NULL. | 202 // be NULL. |
| 105 base::TerminationStatus GetChildTerminationStatus(bool known_dead, | 203 base::TerminationStatus GetChildTerminationStatus(bool known_dead, |
| 106 int* exit_code); | 204 int* exit_code); |
| 107 | 205 |
| 108 // Changes whether the process runs in the background or not. Only call | 206 // Changes whether the process runs in the background or not. Only call |
| 109 // this after the process has started. | 207 // this after the process has started. |
| 110 void SetProcessBackgrounded(bool background); | 208 void SetProcessBackgrounded(bool background); |
| 111 | 209 |
| 210 // Terminates the process. | |
| 211 // Returns true if the process was stopped, false if the process had not been | |
| 212 // started yet or could not be stopped. | |
| 213 // Note that |exit_code| and |wait| are not used on Android. | |
| 214 bool Terminate(int exit_code, bool wait); | |
| 215 | |
| 216 // Similar to Terminate() but takes in a |process|, expected to have been | |
| 217 // started by ChildProcessLauncher. | |
| 218 static bool TerminateProcess(const base::Process& process, | |
| 219 int exit_code, | |
| 220 bool wait); | |
| 221 | |
| 112 // Replaces the ChildProcessLauncher::Client for testing purposes. Returns the | 222 // Replaces the ChildProcessLauncher::Client for testing purposes. Returns the |
| 113 // previous client. | 223 // previous client. |
| 114 Client* ReplaceClientForTest(Client* client); | 224 Client* ReplaceClientForTest(Client* client); |
| 115 | 225 |
| 116 private: | 226 private: |
| 117 // Posts a task to the launcher thread to do the actual work. | 227 static void Terminate(ZygoteHandle zygote, base::Process process); |
| 118 void Launch(std::unique_ptr<SandboxedProcessLauncherDelegate> delegate, | 228 static void TerminateOnLauncherThread( |
| 119 std::unique_ptr<base::CommandLine> cmd_line, | 229 ZygoteHandle zygote, base::Process process); |
| 120 int child_process_id); | 230 static void SetProcessBackgroundedOnLauncherThread( |
| 231 base::Process process, bool background); | |
| 121 | 232 |
| 122 void UpdateTerminationStatus(bool known_dead); | 233 void UpdateTerminationStatus(bool known_dead); |
| 123 | 234 |
| 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. | 235 // Notifies the client about the result of the operation. |
| 139 void Notify(ZygoteHandle zygote, | 236 void Notify(ZygoteHandle zygote, |
| 140 mojo::edk::ScopedPlatformHandle server_handle, | 237 mojo::edk::ScopedPlatformHandle server_handle, |
| 141 base::Process process, | 238 base::Process process, |
| 142 int error_code); | 239 int error_code); |
| 143 | 240 |
| 144 Client* client_; | 241 Client* client_; |
| 145 BrowserThread::ID client_thread_id_; | 242 BrowserThread::ID client_thread_id_; |
| 146 base::Process process_; | 243 base::Process process_; |
| 147 base::TerminationStatus termination_status_; | 244 base::TerminationStatus termination_status_; |
| 148 int exit_code_; | 245 int exit_code_; |
| 149 ZygoteHandle zygote_; | 246 ZygoteHandle zygote_; |
| 150 bool starting_; | 247 bool starting_; |
| 151 const mojo::edk::ProcessErrorCallback process_error_callback_; | 248 const mojo::edk::ProcessErrorCallback process_error_callback_; |
| 152 | 249 |
| 153 // Controls whether the child process should be terminated on browser | 250 // Controls whether the child process should be terminated on browser |
| 154 // shutdown. Default behavior is to terminate the child. | 251 // shutdown. Default behavior is to terminate the child. |
| 155 const bool terminate_child_on_shutdown_; | 252 const bool terminate_child_on_shutdown_; |
| 156 | 253 |
| 157 const std::string mojo_child_token_; | 254 const std::string mojo_child_token_; |
| 158 | 255 |
| 256 scoped_refptr<Helper> helper_; | |
| 257 | |
| 159 base::WeakPtrFactory<ChildProcessLauncher> weak_factory_; | 258 base::WeakPtrFactory<ChildProcessLauncher> weak_factory_; |
| 160 | 259 |
| 161 DISALLOW_COPY_AND_ASSIGN(ChildProcessLauncher); | 260 DISALLOW_COPY_AND_ASSIGN(ChildProcessLauncher); |
| 162 }; | 261 }; |
| 163 | 262 |
| 164 } // namespace content | 263 } // namespace content |
| 165 | 264 |
| 166 #endif // CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_ | 265 #endif // CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_H_ |
| OLD | NEW |