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

Unified Diff: content/browser/child_process_launcher_helper.cc

Issue 2594203004: Unifying ChildProcessLauncher across platforms. (Closed)
Patch Set: Clean-up. 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/child_process_launcher_helper.cc
diff --git a/content/browser/child_process_launcher_helper.cc b/content/browser/child_process_launcher_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9aa83459ba904dbf4e7db6a08f125a156cdda4a9
--- /dev/null
+++ b/content/browser/child_process_launcher_helper.cc
@@ -0,0 +1,165 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/child_process_launcher_helper.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "content/browser/child_process_launcher.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/sandboxed_process_launcher_delegate.h"
+#include "mojo/edk/embedder/platform_channel_pair.h"
+
+namespace content {
+namespace internal {
+
+namespace {
+
+void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) {
+ DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
+ // Log the launch time, separating out the first one (which will likely be
+ // slower due to the rest of the browser initializing at the same time).
+ static bool done_first_launch = false;
+ if (done_first_launch) {
+ UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time);
+ } else {
+ UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time);
+ done_first_launch = true;
+ }
+}
+
+} // namespace
+
+ChildProcessLauncherHelper::Process::Process(Process&& other)
+ : process(std::move(other.process))
+#if defined(OS_LINUX)
+ , zygote(other.zygote)
+#endif
+{
+}
+
+ChildProcessLauncherHelper::Process&
+ChildProcessLauncherHelper::Process::Process::operator=(
+ ChildProcessLauncherHelper::Process&& other) {
+ DCHECK_NE(this, &other);
+ process = std::move(other.process);
+#if defined(OS_LINUX)
+ zygote = other.zygote;
+#endif
+ return *this;
+}
+
+ChildProcessLauncherHelper::ChildProcessLauncherHelper(
+ int child_process_id,
+ BrowserThread::ID client_thread_id,
+ std::unique_ptr<base::CommandLine> command_line,
+ std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
+ const base::WeakPtr<ChildProcessLauncher>& child_process_launcher,
+ bool terminate_on_shutdown)
+ : child_process_id_(child_process_id),
+ client_thread_id_(client_thread_id),
+ command_line_(std::move(command_line)),
+ delegate_(std::move(delegate)),
+ child_process_launcher_(child_process_launcher),
+ terminate_on_shutdown_(terminate_on_shutdown) {
+}
+
+ChildProcessLauncherHelper::~ChildProcessLauncherHelper() {
+}
+
+void ChildProcessLauncherHelper::StartLaunchOnClientThread() {
+ DCHECK_CURRENTLY_ON(client_thread_id_);
+
+ BeforeLaunchOnClientThread();
+
+ mojo_server_handle_ = PrepareMojoPipeHandlesOnClientThread();
+ if (!mojo_server_handle_.is_valid()) {
+ mojo::edk::PlatformChannelPair channel_pair;
+ mojo_server_handle_ = channel_pair.PassServerHandle();
+ mojo_client_handle_ = channel_pair.PassClientHandle();
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
+ base::Bind(&ChildProcessLauncherHelper::LaunchOnLauncherThread, this));
+}
+
+void ChildProcessLauncherHelper::LaunchOnLauncherThread() {
+ DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
+
+ begin_launch_time_ = base::TimeTicks::Now();
+
+ std::unique_ptr<FileMappedForLaunch> files_to_register = GetFilesToMap();
+
+ bool is_synchronous_launch = true;
+ int launch_result = LAUNCH_RESULT_FAILURE;
+ base::LaunchOptions options;
+ BeforeLaunchOnLauncherThread(*files_to_register, &options);
+
+ Process process = LaunchProcessOnLauncherThread(options,
+ std::move(files_to_register),
+ &is_synchronous_launch,
+ &launch_result);
+
+ AfterLaunchOnLauncherThread(process, options);
+
+ if (is_synchronous_launch) {
+ PostLaunchOnLauncherThread(std::move(process), launch_result, false);
+ }
+}
+
+void ChildProcessLauncherHelper::PostLaunchOnLauncherThread(
+ ChildProcessLauncherHelper::Process process,
+ int launch_result,
+ bool post_launch_on_client_thread_called) {
+ // Release the client handle now that the process has been started (the pipe
+ // may not signal when the process dies otherwise and we would not detect the
+ // child process died).
+ mojo_client_handle_.reset();
+
+ if (process.process.IsValid()) {
+ RecordHistogramsOnLauncherThread(
+ base::TimeTicks::Now() - begin_launch_time_);
+ }
+
+ if (!post_launch_on_client_thread_called) {
+ BrowserThread::PostTask(
+ client_thread_id_, FROM_HERE,
+ base::Bind(&ChildProcessLauncherHelper::PostLaunchOnClientThread,
+ this, base::Passed(&process), launch_result));
+ }
+}
+
+void ChildProcessLauncherHelper::PostLaunchOnClientThread(
+ ChildProcessLauncherHelper::Process process,
+ int error_code) {
+ if (child_process_launcher_) {
+ child_process_launcher_->Notify(
+ std::move(process), std::move(mojo_server_handle_), error_code);
+ } else if (process.process.IsValid() && terminate_on_shutdown_) {
+ // Client is gone, terminate the process.
+ ForceNormalProcessTerminationAsync(std::move(process));
+ }
+}
+
+std::string ChildProcessLauncherHelper::GetProcessType() {
+ return command_line()->GetSwitchValueASCII(switches::kProcessType);
+}
+
+// static
+void ChildProcessLauncherHelper::ForceNormalProcessTerminationAsync(
+ ChildProcessLauncherHelper::Process process) {
+ if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) {
+ ForceNormalProcessTerminationSync(std::move(process));
+ return;
+ }
+ // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep!
+ // So don't do this on the UI/IO threads.
+ BrowserThread::PostTask(
+ BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
+ base::Bind(&ChildProcessLauncherHelper::ForceNormalProcessTerminationSync,
+ base::Passed(&process)));
+}
+
+} // namespace internal
+} // namespace content
« no previous file with comments | « content/browser/child_process_launcher_helper.h ('k') | content/browser/child_process_launcher_helper_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698