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

Unified Diff: base/mp/mp_child_process_host.cc

Issue 1625015: Refactor ChildProcess and related classes to create a framework outside of br... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 10 years, 8 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
« no previous file with comments | « base/mp/mp_child_process_host.h ('k') | base/mp/mp_child_process_launcher.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/mp/mp_child_process_host.cc
===================================================================
--- base/mp/mp_child_process_host.cc (revision 0)
+++ base/mp/mp_child_process_host.cc (revision 0)
@@ -0,0 +1,190 @@
+// Copyright (c) 2010 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 "base/mp/mp_child_process_host.h"
+
+#include "base/command_line.h"
+#include "base/compiler_specific.h"
+#include "base/file_path.h"
+#include "base/histogram.h"
+#include "base/logging.h"
+#include "base/mp/mp_child_process_context.h"
+#include "base/mp/mp_messages.h"
+#include "base/path_service.h"
+#include "base/process_util.h"
+#include "base/singleton.h"
+#include "base/string_util.h"
+#include "base/waitable_event.h"
+
+#if defined(OS_LINUX)
+#include "base/linux_util.h"
+#endif // OS_LINUX
+
+
+namespace base {
+
+namespace {
+
+typedef std::list<MpChildProcessHost*> ChildProcessList;
+
+} // namespace
+
+MpChildProcessHost::MpChildProcessHost(MpChildProcessContext* context)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)),
+ context_(context),
+ opening_channel_(false) {
+ Singleton<ChildProcessList>::get()->push_back(this);
+}
+
+
+MpChildProcessHost::~MpChildProcessHost() {
+ Singleton<ChildProcessList>::get()->remove(this);
+}
+
+void MpChildProcessHost::Launch(
+#if defined(OS_WIN)
+ const FilePath& exposed_dir,
+#elif defined(OS_POSIX)
+ bool use_zygote,
+ const base::environment_vector& environ,
+#endif
+ CommandLine* cmd_line) {
+ child_process_.reset(new MpChildProcessLauncher(
+#if defined(OS_WIN)
+ exposed_dir,
+#elif defined(OS_POSIX)
+ use_zygote,
+ environ,
+ channel_->GetClientFileDescriptor(),
+#endif
+ cmd_line,
+ context_,
+ &listener_));
+}
+
+bool MpChildProcessHost::CreateChannel() {
+ channel_id_ = context_->GenerateRandomChannelID(this);
+ channel_.reset(new IPC::Channel(
+ channel_id_, IPC::Channel::MODE_SERVER, &listener_));
+ if (!channel_->Connect())
+ return false;
+
+ opening_channel_ = true;
+
+ return true;
+}
+
+void MpChildProcessHost::InstanceCreated() {
+ Notify(CHILD_INSTANCE_CREATED);
+}
+
+bool MpChildProcessHost::Send(IPC::Message* msg) {
+ if (!channel_.get()) {
+ delete msg;
+ return false;
+ }
+ return channel_->Send(msg);
+}
+
+bool MpChildProcessHost::DidChildCrash() {
+ return child_process_->DidProcessCrash();
+}
+
+void MpChildProcessHost::OnChildDied() {
+ if (GetHandle() != base::kNullProcessHandle) {
+ bool did_crash = DidChildCrash();
+ if (did_crash) {
+ OnProcessCrashed();
+ // Report that this child process crashed.
+ Notify(CHILD_PROCESS_CRASHED);
+ UMA_HISTOGRAM_COUNTS("ChildProcess.Crashes", GetType());
+ }
+ // Notify in the main loop of the disconnection.
+ Notify(CHILD_PROCESS_HOST_DISCONNECTED);
+ }
+
+ delete this;
+}
+
+MpChildProcessHost::ListenerHook::ListenerHook(MpChildProcessHost* host)
+ : host_(host) {
+}
+
+void MpChildProcessHost::ListenerHook::OnMessageReceived(
+ const IPC::Message& msg) {
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging* logger = IPC::Logging::current();
+ if (msg.type() == IPC_LOGGING_ID) {
+ logger->OnReceivedLoggingMessage(msg);
+ return;
+ }
+
+ if (logger->Enabled())
+ logger->OnPreDispatchMessage(msg);
+#endif
+
+ bool msg_is_ok = true;
+ bool handled = host_->OnDispatchMessageReceived(msg, &msg_is_ok);
+
+ if (!handled) {
+ if (msg.type() == MultiProcessHostMsg_ShutdownRequest::ID) {
+ // Must remove the process from the list now, in case it gets used for a
+ // new instance before our watcher tells us that the process terminated.
+ Singleton<ChildProcessList>::get()->remove(host_);
+ if (host_->CanShutdown())
+ host_->Send(new MultiProcessMsg_Shutdown());
+ } else {
+ host_->OnMessageReceived(msg);
+ }
+ }
+
+ if (!msg_is_ok) {
+ base::KillProcess(host_->GetHandle(),
+ host_->context_->GetBadMessageResultCode(), false);
+ }
+
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ if (logger->Enabled())
+ logger->OnPostDispatchMessage(msg, host_->channel_id_);
+#endif
+}
+
+void MpChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) {
+ host_->opening_channel_ = false;
+ host_->OnChannelConnected(peer_pid);
+
+#if defined(IPC_MESSAGE_LOG_ENABLED)
+ bool enabled = IPC::Logging::current()->Enabled();
+ host_->Send(new MultiProcessMsg_SetIPCLoggingEnabled(enabled));
+#endif
+
+ host_->Send(new MultiProcessMsg_AskBeforeShutdown());
+
+ // Notify in the main loop of the connection.
+ host_->Notify(CHILD_PROCESS_HOST_CONNECTED);
+}
+
+void MpChildProcessHost::ListenerHook::OnChannelError() {
+ host_->opening_channel_ = false;
+ host_->OnChannelError();
+
+ // This will delete host_, which will also destroy this!
+ host_->OnChildDied();
+}
+
+void MpChildProcessHost::ListenerHook::OnProcessLaunched() {
+ if (!host_->child_process_->GetHandle()) {
+ delete this;
+ return;
+ }
+
+ host_->OnProcessLaunched();
+}
+
+void MpChildProcessHost::ForceShutdown() {
+ Singleton<ChildProcessList>::get()->remove(this);
+ Send(new MultiProcessMsg_Shutdown());
+}
+
+} // namespace base
« no previous file with comments | « base/mp/mp_child_process_host.h ('k') | base/mp/mp_child_process_launcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698