summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc1
-rw-r--r--chrome/browser/nacl_host/nacl_broker_host_win.cc6
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc54
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.h3
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/service/service_child_process_host.cc45
-rw-r--r--chrome/service/service_child_process_host.h40
-rw-r--r--chrome/service/service_utility_process_host.cc56
-rw-r--r--chrome/service/service_utility_process_host.h36
-rw-r--r--content/browser/browser_child_process_host.cc32
-rw-r--r--content/browser/browser_child_process_host.h30
-rw-r--r--content/browser/gpu/gpu_process_host.cc58
-rw-r--r--content/browser/gpu/gpu_process_host.h2
-rw-r--r--content/browser/plugin_data_remover_impl.cc1
-rw-r--r--content/browser/plugin_loader_posix.cc1
-rw-r--r--content/browser/plugin_process_host.cc21
-rw-r--r--content/browser/plugin_process_host.h6
-rw-r--r--content/browser/ppapi_plugin_process_host.cc14
-rw-r--r--content/browser/ppapi_plugin_process_host.h1
-rw-r--r--content/browser/renderer_host/render_message_filter.cc3
-rw-r--r--content/browser/utility_process_host.cc16
-rw-r--r--content/browser/utility_process_host.h1
-rw-r--r--content/browser/worker_host/worker_process_host.cc33
-rw-r--r--content/common/child_process_host.cc107
-rw-r--r--content/common/child_process_host.h72
-rw-r--r--content/content_common.gypi1
-rw-r--r--content/public/common/child_process_host_delegate.h36
27 files changed, 308 insertions, 370 deletions
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index e4d5776..c2aa4ec 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -117,6 +117,7 @@
#include "content/browser/plugin_service.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/interstitial_page.h"
+#include "content/common/child_process_host.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/common_param_traits.h"
diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.cc b/chrome/browser/nacl_host/nacl_broker_host_win.cc
index 8bd6077..0c05a8d 100644
--- a/chrome/browser/nacl_host/nacl_broker_host_win.cc
+++ b/chrome/browser/nacl_host/nacl_broker_host_win.cc
@@ -14,6 +14,7 @@
#include "chrome/common/logging_chrome.h"
#include "chrome/common/nacl_cmd_line.h"
#include "chrome/common/nacl_messages.h"
+#include "content/common/child_process_host.h"
NaClBrokerHost::NaClBrokerHost()
: BrowserChildProcessHost(content::PROCESS_TYPE_NACL_BROKER),
@@ -25,7 +26,7 @@ NaClBrokerHost::~NaClBrokerHost() {
bool NaClBrokerHost::Init() {
// Create the channel that will be used for communicating with the broker.
- if (!CreateChannel())
+ if (!child_process_host()->CreateChannel())
return false;
// Create the path to the nacl broker/loader executable.
@@ -39,7 +40,8 @@ bool NaClBrokerHost::Init() {
cmd_line->AppendSwitchASCII(switches::kProcessType,
switches::kNaClBrokerProcess);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID,
+ child_process_host()->channel_id());
if (logging::DialogsAreSuppressed())
cmd_line->AppendSwitch(switches::kNoErrorDialogs);
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index c84f416..46a030c 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -23,6 +23,7 @@
#include "chrome/common/nacl_messages.h"
#include "chrome/common/render_messages.h"
#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
+#include "content/common/child_process_host.h"
#include "ipc/ipc_switches.h"
#include "native_client/src/shared/imc/nacl_imc.h"
@@ -116,6 +117,21 @@ NaClProcessHost::NaClProcessHost(const std::wstring& url)
}
NaClProcessHost::~NaClProcessHost() {
+ int exit_code;
+ GetChildTerminationStatus(&exit_code);
+ std::string message =
+ base::StringPrintf("NaCl process exited with status %i (0x%x)",
+ exit_code, exit_code);
+ if (exit_code == 0) {
+ LOG(INFO) << message;
+ } else {
+ LOG(ERROR) << message;
+ }
+
+#if defined(OS_WIN)
+ NaClBrokerService::GetInstance()->OnLoaderDied();
+#endif
+
for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
if (nacl::Close(internal_->sockets_for_renderer[i]) != 0) {
LOG(ERROR) << "nacl::Close() failed";
@@ -212,7 +228,7 @@ bool NaClProcessHost::Launch(
}
bool NaClProcessHost::LaunchSelLdr() {
- if (!CreateChannel())
+ if (!child_process_host()->CreateChannel())
return false;
CommandLine::StringType nacl_loader_prefix;
@@ -230,14 +246,15 @@ bool NaClProcessHost::LaunchSelLdr() {
// to accomodate this request will exist in the child process' address
// space. Disable PIE for NaCl processes. See http://crbug.com/90221 and
// http://code.google.com/p/nativeclient/issues/detail?id=2043.
- int flags = CHILD_NO_PIE;
+ int flags = ChildProcessHost::CHILD_NO_PIE;
#elif defined(OS_LINUX)
- int flags = nacl_loader_prefix.empty() ? CHILD_ALLOW_SELF : CHILD_NORMAL;
+ int flags = nacl_loader_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
+ ChildProcessHost::CHILD_NORMAL;
#else
- int flags = CHILD_NORMAL;
+ int flags = ChildProcessHost::CHILD_NORMAL;
#endif
- FilePath exe_path = GetChildPath(flags);
+ FilePath exe_path = ChildProcessHost::GetChildPath(flags);
if (exe_path.empty())
return false;
@@ -246,7 +263,8 @@ bool NaClProcessHost::LaunchSelLdr() {
cmd_line->AppendSwitchASCII(switches::kProcessType,
switches::kNaClLoaderProcess);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID,
+ child_process_host()->channel_id());
if (logging::DialogsAreSuppressed())
cmd_line->AppendSwitch(switches::kNoErrorDialogs);
@@ -257,7 +275,7 @@ bool NaClProcessHost::LaunchSelLdr() {
#if defined(OS_WIN)
if (RunningOnWOW64()) {
return NaClBrokerService::GetInstance()->LaunchLoader(
- this, ASCIIToWide(channel_id()));
+ this, ASCIIToWide(child_process_host()->channel_id()));
} else {
BrowserChildProcessHost::Launch(FilePath(), cmd_line);
}
@@ -282,24 +300,6 @@ base::TerminationStatus NaClProcessHost::GetChildTerminationStatus(
return BrowserChildProcessHost::GetChildTerminationStatus(exit_code);
}
-void NaClProcessHost::OnChildDied() {
- int exit_code;
- GetChildTerminationStatus(&exit_code);
- std::string message =
- base::StringPrintf("NaCl process exited with status %i (0x%x)",
- exit_code, exit_code);
- if (exit_code == 0) {
- LOG(INFO) << message;
- } else {
- LOG(ERROR) << message;
- }
-
-#if defined(OS_WIN)
- NaClBrokerService::GetInstance()->OnLoaderDied();
-#endif
- BrowserChildProcessHost::OnChildDied();
-}
-
// This only ever runs on the BrowserThread::FILE thread.
// If multiple tasks are posted, the later ones are no-ops.
void NaClBrowser::OpenIrtLibraryFile() {
@@ -519,7 +519,3 @@ bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
NOTREACHED() << "Invalid message with type = " << msg.type();
return false;
}
-
-bool NaClProcessHost::CanShutdown() {
- return true;
-}
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
index 1ccb0f8..c2d8d8f 100644
--- a/chrome/browser/nacl_host/nacl_process_host.h
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -43,7 +43,6 @@ class NaClProcessHost : public BrowserChildProcessHost {
protected:
virtual base::TerminationStatus GetChildTerminationStatus(
int* exit_code) OVERRIDE;
- virtual void OnChildDied() OVERRIDE;
private:
// Internal class that holds the nacl::Handle objecs so that
@@ -59,8 +58,6 @@ class NaClProcessHost : public BrowserChildProcessHost {
void IrtReady();
void SendStart(base::PlatformFile irt_file);
- virtual bool CanShutdown() OVERRIDE;
-
private:
// The ChromeRenderMessageFilter that requested this NaCl process. We use
// this for sending the reply once the process has started.
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 854a235..f8d1793 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -604,8 +604,6 @@
'sources': [
'service/chrome_service_application_mac.h',
'service/chrome_service_application_mac.mm',
- 'service/service_child_process_host.cc',
- 'service/service_child_process_host.h',
'service/service_ipc_server.cc',
'service/service_ipc_server.h',
'service/service_main.cc',
diff --git a/chrome/service/service_child_process_host.cc b/chrome/service/service_child_process_host.cc
deleted file mode 100644
index 234b899..0000000
--- a/chrome/service/service_child_process_host.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2011 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 "chrome/service/service_child_process_host.h"
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/process_util.h"
-#include "chrome/common/chrome_switches.h"
-#include "content/public/common/result_codes.h"
-
-#if defined(OS_WIN)
-#include "base/file_path.h"
-#include "content/common/sandbox_policy.h"
-#endif // defined(OS_WIN)
-
-ServiceChildProcessHost::ServiceChildProcessHost()
- : handle_(base::kNullProcessHandle) {
-}
-
-ServiceChildProcessHost::~ServiceChildProcessHost() {
- // We need to kill the child process when the host dies.
- base::KillProcess(handle_, content::RESULT_CODE_NORMAL_EXIT, false);
-}
-
-bool ServiceChildProcessHost::Launch(CommandLine* cmd_line,
- bool no_sandbox,
- const FilePath& exposed_dir) {
-#if !defined(OS_WIN)
- // TODO(sanjeevr): Implement for non-Windows OSes.
- NOTIMPLEMENTED();
- return false;
-#else // !defined(OS_WIN)
-
- if (no_sandbox) {
- base::ProcessHandle process = base::kNullProcessHandle;
- cmd_line->AppendSwitch(switches::kNoSandbox);
- base::LaunchProcess(*cmd_line, base::LaunchOptions(), &handle_);
- } else {
- handle_ = sandbox::StartProcessWithAccess(cmd_line, exposed_dir);
- }
- return (handle_ != base::kNullProcessHandle);
-#endif // !defined(OS_WIN)
-}
diff --git a/chrome/service/service_child_process_host.h b/chrome/service/service_child_process_host.h
deleted file mode 100644
index 44337be..0000000
--- a/chrome/service/service_child_process_host.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2011 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.
-
-#ifndef CHROME_SERVICE_SERVICE_CHILD_PROCESS_HOST_H_
-#define CHROME_SERVICE_SERVICE_CHILD_PROCESS_HOST_H_
-#pragma once
-
-#include "base/process.h"
-#include "content/common/child_process_host.h"
-
-class CommandLine;
-
-// Plugins/workers and other child processes that live on the IO thread should
-// derive from this class.
-//
-class ServiceChildProcessHost : public ChildProcessHost {
- public:
- virtual ~ServiceChildProcessHost();
-
- protected:
- ServiceChildProcessHost();
-
- // Derived classes call this to launch the child process synchronously.
- // TODO(sanjeevr): Determine whether we need to make the launch asynchronous.
- // |exposed_dir| is the path to tbe exposed to the sandbox. This is ignored
- // if |no_sandbox| is true.
- bool Launch(CommandLine* cmd_line,
- bool no_sandbox,
- const FilePath& exposed_dir);
-
- base::ProcessHandle handle() const { return handle_; }
-
- private:
- base::ProcessHandle handle_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceChildProcessHost);
-};
-
-#endif // CHROME_SERVICE_SERVICE_CHILD_PROCESS_HOST_H_
diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc
index 8352526..d82007a 100644
--- a/chrome/service/service_utility_process_host.cc
+++ b/chrome/service/service_utility_process_host.cc
@@ -7,31 +7,41 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
+#include "base/logging.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
+#include "base/process_util.h"
#include "base/scoped_temp_dir.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_utility_messages.h"
+#include "content/common/child_process_host.h"
+#include "content/public/common/result_codes.h"
#include "ipc/ipc_switches.h"
#include "printing/page_range.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/rect.h"
#if defined(OS_WIN)
+#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/win/scoped_handle.h"
+#include "content/common/sandbox_policy.h"
#include "printing/emf_win.h"
#endif
ServiceUtilityProcessHost::ServiceUtilityProcessHost(
Client* client, base::MessageLoopProxy* client_message_loop_proxy)
- : client_(client),
+ : handle_(base::kNullProcessHandle),
+ client_(client),
client_message_loop_proxy_(client_message_loop_proxy),
waiting_for_reply_(false) {
+ child_process_host_.reset(new ChildProcessHost(this));
}
ServiceUtilityProcessHost::~ServiceUtilityProcessHost() {
+ // We need to kill the child process when the host dies.
+ base::KillProcess(handle_, content::RESULT_CODE_NORMAL_EXIT, false);
}
bool ServiceUtilityProcessHost::StartRenderPDFPagesToMetafile(
@@ -72,7 +82,7 @@ bool ServiceUtilityProcessHost::StartRenderPDFPagesToMetafile(
if (!pdf_file_in_utility_process)
return false;
waiting_for_reply_ = true;
- return Send(
+ return child_process_host_->Send(
new ChromeUtilityMsg_RenderPDFPagesToMetafile(
pdf_file_in_utility_process,
metafile_path_,
@@ -87,12 +97,13 @@ bool ServiceUtilityProcessHost::StartGetPrinterCapsAndDefaults(
if (!StartProcess(true, exposed_path))
return false;
waiting_for_reply_ = true;
- return Send(new ChromeUtilityMsg_GetPrinterCapsAndDefaults(printer_name));
+ return child_process_host_->Send(
+ new ChromeUtilityMsg_GetPrinterCapsAndDefaults(printer_name));
}
bool ServiceUtilityProcessHost::StartProcess(bool no_sandbox,
const FilePath& exposed_dir) {
- if (!CreateChannel())
+ if (!child_process_host_->CreateChannel())
return false;
FilePath exe_path = GetUtilityProcessCmd();
@@ -103,34 +114,57 @@ bool ServiceUtilityProcessHost::StartProcess(bool no_sandbox,
CommandLine cmd_line(exe_path);
cmd_line.AppendSwitchASCII(switches::kProcessType, switches::kUtilityProcess);
- cmd_line.AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+ cmd_line.AppendSwitchASCII(switches::kProcessChannelID,
+ child_process_host_->channel_id());
cmd_line.AppendSwitch(switches::kLang);
return Launch(&cmd_line, no_sandbox, exposed_dir);
}
+bool ServiceUtilityProcessHost::Launch(CommandLine* cmd_line,
+ bool no_sandbox,
+ const FilePath& exposed_dir) {
+#if !defined(OS_WIN)
+ // TODO(sanjeevr): Implement for non-Windows OSes.
+ NOTIMPLEMENTED();
+ return false;
+#else // !defined(OS_WIN)
+
+ if (no_sandbox) {
+ base::ProcessHandle process = base::kNullProcessHandle;
+ cmd_line->AppendSwitch(switches::kNoSandbox);
+ base::LaunchProcess(*cmd_line, base::LaunchOptions(), &handle_);
+ } else {
+ handle_ = sandbox::StartProcessWithAccess(cmd_line, exposed_dir);
+ }
+ return (handle_ != base::kNullProcessHandle);
+#endif // !defined(OS_WIN)
+}
+
FilePath ServiceUtilityProcessHost::GetUtilityProcessCmd() {
#if defined(OS_LINUX)
- int flags = CHILD_ALLOW_SELF;
+ int flags = ChildProcessHost::CHILD_ALLOW_SELF;
#else
- int flags = CHILD_NORMAL;
+ int flags = ChildProcessHost::CHILD_NORMAL;
#endif
- return GetChildPath(flags);
+ return ChildProcessHost::GetChildPath(flags);
}
bool ServiceUtilityProcessHost::CanShutdown() {
return true;
}
-void ServiceUtilityProcessHost::OnChildDied() {
+void ServiceUtilityProcessHost::OnChildDisconnected() {
if (waiting_for_reply_) {
// If we are yet to receive a reply then notify the client that the
// child died.
client_message_loop_proxy_->PostTask(
FROM_HERE, base::Bind(&Client::OnChildDied, client_.get()));
}
- // The base class implementation will delete |this|.
- ServiceChildProcessHost::OnChildDied();
+ delete this;
+}
+
+void ServiceUtilityProcessHost::ShutdownStarted() {
}
bool ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
diff --git a/chrome/service/service_utility_process_host.h b/chrome/service/service_utility_process_host.h
index 49e2450..77cb2f7 100644
--- a/chrome/service/service_utility_process_host.h
+++ b/chrome/service/service_utility_process_host.h
@@ -14,11 +14,15 @@
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/process.h"
#include "base/task.h"
#include "ipc/ipc_channel.h"
-#include "chrome/service/service_child_process_host.h"
+#include "content/public/common/child_process_host_delegate.h"
#include "printing/pdf_render_settings.h"
+class ChildProcessHost;
+class CommandLine;
class ScopedTempDir;
namespace base {
@@ -34,7 +38,7 @@ struct PrinterCapsAndDefaults;
// Acts as the service-side host to a utility child process. A
// utility process is a short-lived sandboxed process that is created to run
// a specific task.
-class ServiceUtilityProcessHost : public ServiceChildProcessHost {
+class ServiceUtilityProcessHost : public content::ChildProcessHostDelegate {
public:
// Consumers of ServiceUtilityProcessHost must implement this interface to
// get results back. All functions are called on the thread passed along
@@ -101,9 +105,11 @@ class ServiceUtilityProcessHost : public ServiceChildProcessHost {
// Allows this method to be overridden for tests.
virtual FilePath GetUtilityProcessCmd();
- // ChildProcessHost implementation.
+ // ChildProcessHostDelegate implementation:
virtual bool CanShutdown() OVERRIDE;
- virtual void OnChildDied() OVERRIDE;
+ virtual void OnChildDisconnected() OVERRIDE;
+ virtual void ShutdownStarted() OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
// Starts a process. Returns true iff it succeeded. |exposed_dir| is the
@@ -111,22 +117,26 @@ class ServiceUtilityProcessHost : public ServiceChildProcessHost {
// true.
bool StartProcess(bool no_sandbox, const FilePath& exposed_dir);
- // IPC messages:
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- // Called when at least one page in the specified PDF has been rendered
- // successfully into metafile_path_;
+ // Launch the child process synchronously.
+ // TODO(sanjeevr): Determine whether we need to make the launch asynchronous.
+ // |exposed_dir| is the path to tbe exposed to the sandbox. This is ignored
+ // if |no_sandbox| is true.
+ bool Launch(CommandLine* cmd_line,
+ bool no_sandbox,
+ const FilePath& exposed_dir);
+
+ base::ProcessHandle handle() const { return handle_; }
+
+ // Messages handlers:
void OnRenderPDFPagesToMetafileSucceeded(int highest_rendered_page_number);
- // Called when PDF rendering failed.
void OnRenderPDFPagesToMetafileFailed();
- // Called when the printer capabilities and defaults have been
- // retrieved successfully.
void OnGetPrinterCapsAndDefaultsSucceeded(
const std::string& printer_name,
const printing::PrinterCapsAndDefaults& caps_and_defaults);
- // Called when the printer capabilities and defaults could not be
- // retrieved successfully.
void OnGetPrinterCapsAndDefaultsFailed(const std::string& printer_name);
+ scoped_ptr<ChildProcessHost> child_process_host_;
+ base::ProcessHandle handle_;
// A pointer to our client interface, who will be informed of progress.
scoped_refptr<Client> client_;
scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy_;
diff --git a/content/browser/browser_child_process_host.cc b/content/browser/browser_child_process_host.cc
index 508dade..3e56b6e 100644
--- a/content/browser/browser_child_process_host.cc
+++ b/content/browser/browser_child_process_host.cc
@@ -17,6 +17,7 @@
#include "content/browser/profiler_message_filter.h"
#include "content/browser/renderer_host/resource_message_filter.h"
#include "content/browser/trace_message_filter.h"
+#include "content/common/child_process_host.h"
#include "content/common/plugin_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
@@ -59,10 +60,11 @@ BrowserChildProcessHost::BrowserChildProcessHost(
#endif
disconnect_was_alive_(false) {
data_.type = type;
- data_.id = GenerateChildProcessUniqueId();
+ data_.id = ChildProcessHost::GenerateChildProcessUniqueId();
- AddFilter(new TraceMessageFilter);
- AddFilter(new ProfilerMessageFilter);
+ child_process_host_.reset(new ChildProcessHost(this));
+ child_process_host_->AddFilter(new TraceMessageFilter);
+ child_process_host_->AddFilter(new ProfilerMessageFilter);
g_child_process_list.Get().push_back(this);
}
@@ -96,7 +98,7 @@ void BrowserChildProcessHost::Launch(
#elif defined(OS_POSIX)
use_zygote,
environ,
- channel()->TakeClientFileDescriptor(),
+ child_process_host()->channel()->TakeClientFileDescriptor(),
#endif
cmd_line,
&client_));
@@ -112,7 +114,7 @@ base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const {
void BrowserChildProcessHost::ForceShutdown() {
g_child_process_list.Get().remove(this);
- ChildProcessHost::ForceShutdown();
+ child_process_host_->ForceShutdown();
}
void BrowserChildProcessHost::SetTerminateChildOnShutdown(
@@ -132,11 +134,19 @@ base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus(
return child_process_->GetChildTerminationStatus(exit_code);
}
+bool BrowserChildProcessHost::OnMessageReceived(const IPC::Message& message) {
+ return false;
+}
+
void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) {
Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED);
}
-// The ChildProcessHost default implementation calls OnChildDied() always but at
+bool BrowserChildProcessHost::CanShutdown() {
+ return true;
+}
+
+// Normally a ChildProcessHostDelegate deletes itself from this callback, but at
// this layer and below we need to have the final child process exit code to
// properly bucket crashes vs kills. On Windows we can do this if we wait until
// the process handle is signaled; on the rest of the platforms, we schedule a
@@ -212,7 +222,7 @@ void BrowserChildProcessHost::OnChildDisconnected() {
content::PROCESS_TYPE_MAX);
// Notify in the main loop of the disconnection.
Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED);
- OnChildDied();
+ delete this;
}
// The child process handle has been signaled so the exit code is finally
@@ -226,13 +236,17 @@ void BrowserChildProcessHost::OnWaitableEventSignaled(
GetExitCodeProcess(waitable_event->Release(), &exit_code);
delete waitable_event;
if (exit_code == STILL_ACTIVE) {
- OnChildDied();
+ delete this;
} else {
BrowserChildProcessHost::OnChildDisconnected();
}
#endif
}
+bool BrowserChildProcessHost::Send(IPC::Message* message) {
+ return child_process_host_->Send(message);
+}
+
void BrowserChildProcessHost::ShutdownStarted() {
// 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.
@@ -245,7 +259,7 @@ BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host)
void BrowserChildProcessHost::ClientHook::OnProcessLaunched() {
if (!host_->child_process_->GetHandle()) {
- host_->OnChildDied();
+ delete host_;
return;
}
host_->data_.handle = host_->child_process_->GetHandle();
diff --git a/content/browser/browser_child_process_host.h b/content/browser/browser_child_process_host.h
index a201c30..561d84e 100644
--- a/content/browser/browser_child_process_host.h
+++ b/content/browser/browser_child_process_host.h
@@ -8,13 +8,17 @@
#include <list>
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process.h"
#include "base/synchronization/waitable_event_watcher.h"
#include "content/browser/child_process_launcher.h"
-#include "content/common/child_process_host.h"
#include "content/common/content_export.h"
#include "content/public/browser/child_process_data.h"
+#include "content/public/common/child_process_host_delegate.h"
+#include "ipc/ipc_message.h"
+
+class ChildProcessHost;
namespace base {
class WaitableEvent;
@@ -26,9 +30,10 @@ class WaitableEvent;
// [Browser]RenderProcessHost is the main exception that doesn't derive from
// this class. That project lives on the UI thread.
class CONTENT_EXPORT BrowserChildProcessHost :
- public ChildProcessHost,
+ public content::ChildProcessHostDelegate,
public ChildProcessLauncher::Client,
- public base::WaitableEventWatcher::Delegate {
+ public base::WaitableEventWatcher::Delegate,
+ public IPC::Message::Sender {
public:
virtual ~BrowserChildProcessHost();
@@ -58,6 +63,9 @@ class CONTENT_EXPORT BrowserChildProcessHost :
std::list<BrowserChildProcessHost*>::iterator iterator_;
};
+ // IPC::Message::Sender override
+ virtual bool Send(IPC::Message* message) OVERRIDE;
+
const content::ChildProcessData& data() const { return data_; }
content::ProcessType type() const { return data_.type; }
const string16& name() const { return data_.name; }
@@ -102,13 +110,15 @@ class CONTENT_EXPORT BrowserChildProcessHost :
// GetExitCodeProcess()). |exit_code| may be NULL.
virtual base::TerminationStatus GetChildTerminationStatus(int* exit_code);
- // Overrides from ChildProcessHost
- virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
+ // ChildProcessHostDelegate implementation:
+ virtual bool CanShutdown() OVERRIDE;
virtual void OnChildDisconnected() OVERRIDE;
virtual void ShutdownStarted() OVERRIDE;
- // Extends the base class implementation and removes this host from
- // the host list. Calls ChildProcessHost::ForceShutdown
- virtual void ForceShutdown() OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
+
+ // Removes this host from the host list. Calls ChildProcessHost::ForceShutdown
+ void ForceShutdown();
// Controls whether the child process should be terminated on browser
// shutdown. Default is to always terminate.
@@ -117,6 +127,9 @@ class CONTENT_EXPORT BrowserChildProcessHost :
// Sends the given notification on the UI thread.
void Notify(int type);
+ ChildProcessHost* child_process_host() const {
+ return child_process_host_.get();
+ }
void set_name(const string16& name) { data_.name = name; }
void set_handle(base::ProcessHandle handle) { data_.handle = handle; }
@@ -133,6 +146,7 @@ class CONTENT_EXPORT BrowserChildProcessHost :
};
content::ChildProcessData data_;
+ scoped_ptr<ChildProcessHost> child_process_host_;
ClientHook client_;
scoped_ptr<ChildProcessLauncher> child_process_;
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index cdaac3e..3b18d38 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -17,6 +17,7 @@
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
#include "content/browser/renderer_host/render_widget_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
+#include "content/common/child_process_host.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/gpu/gpu_process.h"
@@ -279,6 +280,25 @@ GpuProcessHost::GpuProcessHost(int host_id)
GpuProcessHost::~GpuProcessHost() {
DCHECK(CalledOnValidThread());
+
+ SendOutstandingReplies();
+ UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
+ DIED_FIRST_TIME + g_gpu_crash_count,
+ GPU_PROCESS_LIFETIME_EVENT_MAX);
+
+ int exit_code;
+ base::TerminationStatus status = GetChildTerminationStatus(&exit_code);
+ UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessTerminationStatus",
+ status,
+ base::TERMINATION_STATUS_MAX_ENUM);
+
+ if (status == base::TERMINATION_STATUS_NORMAL_TERMINATION ||
+ status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) {
+ UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessExitCode",
+ exit_code,
+ content::RESULT_CODE_LAST_CODE);
+ }
+
#if defined(OS_WIN)
if (gpu_process_)
CloseHandle(gpu_process_);
@@ -299,14 +319,15 @@ GpuProcessHost::~GpuProcessHost() {
}
bool GpuProcessHost::Init() {
- if (!CreateChannel())
+ if (!child_process_host()->CreateChannel())
return false;
if (in_process_) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisableGpuWatchdog);
- in_process_gpu_thread_.reset(new GpuMainThread(channel_id()));
+ in_process_gpu_thread_.reset(new GpuMainThread(
+ child_process_host()->channel_id()));
base::Thread::Options options;
#if defined(OS_WIN)
@@ -337,7 +358,7 @@ void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) {
bool GpuProcessHost::Send(IPC::Message* msg) {
DCHECK(CalledOnValidThread());
- if (opening_channel()) {
+ if (child_process_host()->opening_channel()) {
queued_messages_.push(msg);
return true;
}
@@ -488,10 +509,6 @@ void GpuProcessHost::OnGraphicsInfoCollected(const content::GPUInfo& gpu_info) {
GpuDataManager::GetInstance()->UpdateGpuInfo(gpu_info);
}
-bool GpuProcessHost::CanShutdown() {
- return true;
-}
-
void GpuProcessHost::OnProcessLaunched() {
// Send the GPU process handle to the UI thread before it has to
// respond to any requests to establish a GPU channel. The response
@@ -513,30 +530,6 @@ void GpuProcessHost::OnProcessLaunched() {
#endif
}
-void GpuProcessHost::OnChildDied() {
- SendOutstandingReplies();
- // Located in OnChildDied because OnProcessCrashed suffers from a race
- // condition on Linux.
- UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
- DIED_FIRST_TIME + g_gpu_crash_count,
- GPU_PROCESS_LIFETIME_EVENT_MAX);
-
- int exit_code;
- base::TerminationStatus status = GetChildTerminationStatus(&exit_code);
- UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessTerminationStatus",
- status,
- base::TERMINATION_STATUS_MAX_ENUM);
-
- if (status == base::TERMINATION_STATUS_NORMAL_TERMINATION ||
- status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) {
- UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessExitCode",
- exit_code,
- content::RESULT_CODE_LAST_CODE);
- }
-
- ChildProcessHost::OnChildDied();
-}
-
void GpuProcessHost::OnProcessCrashed(int exit_code) {
SendOutstandingReplies();
if (++g_gpu_crash_count >= kGpuMaxCrashCount) {
@@ -575,7 +568,8 @@ bool GpuProcessHost::LaunchGpuProcess() {
CommandLine* cmd_line = new CommandLine(exe_path);
cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID,
+ child_process_host()->channel_id());
// Propagate relevant command line switches.
static const char* const kSwitchNames[] = {
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index e6ba2c0..073e8fd 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -92,9 +92,7 @@ class GpuProcessHost : public BrowserChildProcessHost,
// Post an IPC message to the UI shim's message handler on the UI thread.
void RouteOnUIThread(const IPC::Message& message);
- virtual bool CanShutdown() OVERRIDE;
virtual void OnProcessLaunched() OVERRIDE;
- virtual void OnChildDied() OVERRIDE;
virtual void OnProcessCrashed(int exit_code) OVERRIDE;
// Message handlers.
diff --git a/content/browser/plugin_data_remover_impl.cc b/content/browser/plugin_data_remover_impl.cc
index da0dbfc..38489d5 100644
--- a/content/browser/plugin_data_remover_impl.cc
+++ b/content/browser/plugin_data_remover_impl.cc
@@ -10,6 +10,7 @@
#include "base/version.h"
#include "content/browser/plugin_process_host.h"
#include "content/browser/plugin_service.h"
+#include "content/common/child_process_host.h"
#include "content/common/plugin_messages.h"
#include "content/public/browser/browser_thread.h"
#include "webkit/plugins/npapi/plugin_group.h"
diff --git a/content/browser/plugin_loader_posix.cc b/content/browser/plugin_loader_posix.cc
index 6d2be85..bc96427 100644
--- a/content/browser/plugin_loader_posix.cc
+++ b/content/browser/plugin_loader_posix.cc
@@ -8,6 +8,7 @@
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/metrics/histogram.h"
+#include "content/common/child_process_host.h"
#include "content/common/utility_messages.h"
#include "content/public/browser/browser_thread.h"
#include "webkit/plugins/npapi/plugin_list.h"
diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc
index 91c22c4..293072d 100644
--- a/content/browser/plugin_process_host.cc
+++ b/content/browser/plugin_process_host.cc
@@ -22,6 +22,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "content/browser/plugin_service.h"
+#include "content/common/child_process_host.h"
#include "content/common/plugin_messages.h"
#include "content/common/resource_messages.h"
#include "content/public/browser/browser_thread.h"
@@ -167,7 +168,7 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info,
info_ = info;
set_name(info_.name);
- if (!CreateChannel())
+ if (!child_process_host()->CreateChannel())
return false;
// Build command line for plugin. When we have a plugin launcher, we can't
@@ -180,14 +181,15 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info,
// Run the plug-in process in a mode tolerant of heap execution without
// explicit mprotect calls. Some plug-ins still rely on this quaint and
// archaic "feature." See http://crbug.com/93551.
- int flags = CHILD_ALLOW_HEAP_EXECUTION;
+ int flags = ChildProcessHost::CHILD_ALLOW_HEAP_EXECUTION;
#elif defined(OS_LINUX)
- int flags = plugin_launcher.empty() ? CHILD_ALLOW_SELF : CHILD_NORMAL;
+ int flags = plugin_launcher.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
+ ChildProcessHost::CHILD_NORMAL;
#else
- int flags = CHILD_NORMAL;
+ int flags = ChildProcessHost::CHILD_NORMAL;
#endif
- FilePath exe_path = GetChildPath(flags);
+ FilePath exe_path = ChildProcessHost::GetChildPath(flags);
if (exe_path.empty())
return false;
@@ -233,7 +235,8 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info,
cmd_line->AppendSwitchASCII(switches::kLang, locale);
}
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID,
+ child_process_host()->channel_id());
#if defined(OS_POSIX)
base::environment_vector env;
@@ -279,6 +282,10 @@ void PluginProcessHost::ForceShutdown() {
BrowserChildProcessHost::ForceShutdown();
}
+void PluginProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
+ child_process_host()->AddFilter(filter);
+}
+
bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PluginProcessHost, msg)
@@ -359,7 +366,7 @@ void PluginProcessHost::CancelPendingRequestsForResourceContext(
void PluginProcessHost::OpenChannelToPlugin(Client* client) {
Notify(content::NOTIFICATION_CHILD_INSTANCE_CREATED);
client->SetPluginInfo(info_);
- if (opening_channel()) {
+ if (child_process_host()->opening_channel()) {
// The channel is already in the process of being opened. Put
// this "open channel" request into a queue of requests that will
// be run once the channel is open.
diff --git a/content/browser/plugin_process_host.h b/content/browser/plugin_process_host.h
index b56183f..6ce5f08 100644
--- a/content/browser/plugin_process_host.h
+++ b/content/browser/plugin_process_host.h
@@ -17,6 +17,7 @@
#include "base/memory/ref_counted.h"
#include "content/browser/browser_child_process_host.h"
#include "content/common/content_export.h"
+#include "ipc/ipc_channel_proxy.h"
#include "webkit/plugins/webplugininfo.h"
#include "ui/gfx/native_widget_types.h"
@@ -69,7 +70,7 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHost {
bool Init(const webkit::WebPluginInfo& info, const std::string& locale);
// Force the plugin process to shutdown (cleanly).
- virtual void ForceShutdown() OVERRIDE;
+ void ForceShutdown();
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
@@ -109,6 +110,9 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHost {
void AddWindow(HWND window);
#endif
+ // Adds an IPC message filter. A reference will be kept to the filter.
+ void AddFilter(IPC::ChannelProxy::MessageFilter* filter);
+
private:
// Sends a message to the plugin process to request creation of a new channel
// for the given mime type.
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc
index 8b5faef..f4ccd33 100644
--- a/content/browser/ppapi_plugin_process_host.cc
+++ b/content/browser/ppapi_plugin_process_host.cc
@@ -11,6 +11,7 @@
#include "base/utf_string_conversions.h"
#include "content/browser/plugin_service.h"
#include "content/browser/renderer_host/render_message_filter.h"
+#include "content/common/child_process_host.h"
#include "content/common/child_process_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/pepper_plugin_info.h"
@@ -84,7 +85,7 @@ PpapiPluginProcessHost* PpapiPluginProcessHost::CreateBrokerHost(
}
void PpapiPluginProcessHost::OpenChannelToPlugin(Client* client) {
- if (opening_channel()) {
+ if (child_process_host()->opening_channel()) {
// The channel is already in the process of being opened. Put
// this "open channel" request into a queue of requests that will
// be run once the channel is open.
@@ -102,7 +103,7 @@ PpapiPluginProcessHost::PpapiPluginProcessHost(net::HostResolver* host_resolver)
network_observer_(new PluginNetworkObserver(this)),
is_broker_(false),
process_id_(ChildProcessHost::GenerateChildProcessUniqueId()) {
- AddFilter(filter_.get());
+ child_process_host()->AddFilter(filter_.get());
}
PpapiPluginProcessHost::PpapiPluginProcessHost()
@@ -119,7 +120,7 @@ bool PpapiPluginProcessHost::Init(const content::PepperPluginInfo& info) {
set_name(UTF8ToUTF16(info.name));
}
- if (!CreateChannel())
+ if (!child_process_host()->CreateChannel())
return false;
const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
@@ -140,7 +141,8 @@ bool PpapiPluginProcessHost::Init(const content::PepperPluginInfo& info) {
cmd_line->AppendSwitchASCII(switches::kProcessType,
is_broker_ ? switches::kPpapiBrokerProcess
: switches::kPpapiPluginProcess);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID,
+ child_process_host()->channel_id());
// These switches are forwarded to both plugin and broker pocesses.
static const char* kCommonForwardSwitches[] = {
@@ -198,10 +200,6 @@ void PpapiPluginProcessHost::RequestPluginChannel(Client* client) {
client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
}
-bool PpapiPluginProcessHost::CanShutdown() {
- return true;
-}
-
void PpapiPluginProcessHost::OnProcessLaunched() {
}
diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h
index a968a27..f92aa1d 100644
--- a/content/browser/ppapi_plugin_process_host.h
+++ b/content/browser/ppapi_plugin_process_host.h
@@ -82,7 +82,6 @@ class PpapiPluginProcessHost
void RequestPluginChannel(Client* client);
- virtual bool CanShutdown() OVERRIDE;
virtual void OnProcessLaunched() OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 267d1cc..f84b968 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -686,8 +686,7 @@ void RenderMessageFilter::OnCheckNotificationPermission(
void RenderMessageFilter::OnAllocateSharedMemory(
uint32 buffer_size,
base::SharedMemoryHandle* handle) {
- ChildProcessHost::OnAllocateSharedMemory(
- buffer_size, peer_handle(), handle);
+ ChildProcessHost::AllocateSharedMemory(buffer_size, peer_handle(), handle);
}
net::URLRequestContext* RenderMessageFilter::GetRequestContextForURL(
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc
index 65a7e70..8bc2234 100644
--- a/content/browser/utility_process_host.cc
+++ b/content/browser/utility_process_host.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
+#include "content/common/child_process_host.h"
#include "content/common/utility_messages.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_switches.h"
@@ -40,9 +41,9 @@ UtilityProcessHost::UtilityProcessHost(Client* client,
is_batch_mode_(false),
no_sandbox_(false),
#if defined(OS_LINUX)
- child_flags_(CHILD_ALLOW_SELF),
+ child_flags_(ChildProcessHost::CHILD_ALLOW_SELF),
#else
- child_flags_(CHILD_NORMAL),
+ child_flags_(ChildProcessHost::CHILD_NORMAL),
#endif
started_(false) {
}
@@ -72,7 +73,7 @@ void UtilityProcessHost::EndBatchMode() {
}
FilePath UtilityProcessHost::GetUtilityProcessCmd() {
- return GetChildPath(child_flags_);
+ return ChildProcessHost::GetChildPath(child_flags_);
}
bool UtilityProcessHost::StartProcess() {
@@ -86,7 +87,7 @@ bool UtilityProcessHost::StartProcess() {
// launches a UtilityProcessHost.
set_name(ASCIIToUTF16("utility process"));
- if (!CreateChannel())
+ if (!child_process_host()->CreateChannel())
return false;
FilePath exe_path = GetUtilityProcessCmd();
@@ -98,7 +99,8 @@ bool UtilityProcessHost::StartProcess() {
CommandLine* cmd_line = new CommandLine(exe_path);
cmd_line->AppendSwitchASCII(switches::kProcessType,
switches::kUtilityProcess);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID,
+ child_process_host()->channel_id());
std::string locale =
content::GetContentClient()->browser()->GetApplicationLocale();
cmd_line->AppendSwitchASCII(switches::kLang, locale);
@@ -151,7 +153,3 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
client_thread_id_, FROM_HERE,
base::Bind(&Client::OnProcessCrashed, client_.get(), exit_code));
}
-
-bool UtilityProcessHost::CanShutdown() {
- return true;
-}
diff --git a/content/browser/utility_process_host.h b/content/browser/utility_process_host.h
index de53610..b81d12d 100644
--- a/content/browser/utility_process_host.h
+++ b/content/browser/utility_process_host.h
@@ -84,7 +84,6 @@ class CONTENT_EXPORT UtilityProcessHost : public BrowserChildProcessHost {
// BrowserChildProcessHost:
virtual void OnProcessCrashed(int exit_code) OVERRIDE;
- virtual bool CanShutdown() OVERRIDE;
// A pointer to our client interface, who will be informed of progress.
scoped_refptr<Client> client_;
diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc
index ba29447..68d75c9 100644
--- a/content/browser/worker_host/worker_process_host.cc
+++ b/content/browser/worker_host/worker_process_host.cc
@@ -31,6 +31,7 @@
#include "content/browser/worker_host/message_port_service.h"
#include "content/browser/worker_host/worker_message_filter.h"
#include "content/browser/worker_host/worker_service.h"
+#include "content/common/child_process_host.h"
#include "content/common/debug_flags.h"
#include "content/common/view_messages.h"
#include "content/common/worker_messages.h"
@@ -111,22 +112,23 @@ WorkerProcessHost::~WorkerProcessHost() {
}
bool WorkerProcessHost::Init(int render_process_id) {
- if (!CreateChannel())
+ if (!child_process_host()->CreateChannel())
return false;
#if defined(OS_LINUX)
- int flags = CHILD_ALLOW_SELF;
+ int flags = ChildProcessHost::CHILD_ALLOW_SELF;
#else
- int flags = CHILD_NORMAL;
+ int flags = ChildProcessHost::CHILD_NORMAL;
#endif
- FilePath exe_path = GetChildPath(flags);
+ FilePath exe_path = ChildProcessHost::GetChildPath(flags);
if (exe_path.empty())
return false;
CommandLine* cmd_line = new CommandLine(exe_path);
cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kWorkerProcess);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
+ cmd_line->AppendSwitchASCII(switches::kProcessChannelID,
+ child_process_host()->channel_id());
std::string locale =
content::GetContentClient()->browser()->GetApplicationLocale();
cmd_line->AppendSwitchASCII(switches::kLang, locale);
@@ -237,29 +239,30 @@ void WorkerProcessHost::CreateMessageFilters(int render_process_id) {
id(), content::PROCESS_TYPE_WORKER, resource_context_,
new URLRequestContextSelector(request_context),
resource_dispatcher_host_);
- AddFilter(resource_message_filter);
+ child_process_host()->AddFilter(resource_message_filter);
worker_message_filter_ = new WorkerMessageFilter(
render_process_id, resource_context_, resource_dispatcher_host_,
base::Bind(&WorkerService::next_worker_route_id,
base::Unretained(WorkerService::GetInstance())));
- AddFilter(worker_message_filter_);
- AddFilter(new AppCacheDispatcherHost(
+ child_process_host()->AddFilter(worker_message_filter_);
+ child_process_host()->AddFilter(new AppCacheDispatcherHost(
resource_context_->appcache_service(), id()));
- AddFilter(new FileSystemDispatcherHost(
+ child_process_host()->AddFilter(new FileSystemDispatcherHost(
request_context, resource_context_->file_system_context()));
- AddFilter(new FileUtilitiesMessageFilter(id()));
- AddFilter(new BlobMessageFilter(
+ child_process_host()->AddFilter(new FileUtilitiesMessageFilter(id()));
+ child_process_host()->AddFilter(new BlobMessageFilter(
id(), resource_context_->blob_storage_context()));
- AddFilter(new MimeRegistryMessageFilter());
- AddFilter(new DatabaseMessageFilter(
+ child_process_host()->AddFilter(new MimeRegistryMessageFilter());
+ child_process_host()->AddFilter(new DatabaseMessageFilter(
resource_context_->database_tracker()));
SocketStreamDispatcherHost* socket_stream_dispatcher_host =
new SocketStreamDispatcherHost(
new URLRequestContextSelector(request_context), resource_context_);
- AddFilter(socket_stream_dispatcher_host);
- AddFilter(new content::WorkerDevToolsMessageFilter(id()));
+ child_process_host()->AddFilter(socket_stream_dispatcher_host);
+ child_process_host()->AddFilter(
+ new content::WorkerDevToolsMessageFilter(id()));
}
void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) {
diff --git a/content/common/child_process_host.cc b/content/common/child_process_host.cc
index fd1de4a..002e016 100644
--- a/content/common/child_process_host.cc
+++ b/content/common/child_process_host.cc
@@ -17,6 +17,7 @@
#include "base/stringprintf.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "content/common/child_process_messages.h"
+#include "content/public/common/child_process_host_delegate.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_logging.h"
@@ -73,8 +74,9 @@ FilePath TransformPathForFeature(const FilePath& path,
} // namespace
#endif // OS_MACOSX
-ChildProcessHost::ChildProcessHost()
- : ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)),
+ChildProcessHost::ChildProcessHost(content::ChildProcessHostDelegate* delegate)
+ : delegate_(delegate),
+ peer_handle_(base::kNullProcessHandle),
opening_channel_(false) {
#if defined(OS_WIN)
AddFilter(new FontCacheDispatcher());
@@ -86,7 +88,8 @@ ChildProcessHost::~ChildProcessHost() {
filters_[i]->OnChannelClosing();
filters_[i]->OnFilterRemoved();
}
- listener_.Shutdown();
+
+ base::CloseProcessHandle(peer_handle_);
}
void ChildProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
@@ -147,7 +150,7 @@ void ChildProcessHost::ForceShutdown() {
bool ChildProcessHost::CreateChannel() {
channel_id_ = GenerateRandomChannelID(this);
channel_.reset(new IPC::Channel(
- channel_id_, IPC::Channel::MODE_SERVER, &listener_));
+ channel_id_, IPC::Channel::MODE_SERVER, this));
if (!channel_->Connect())
return false;
@@ -167,16 +170,6 @@ bool ChildProcessHost::CreateChannel() {
return true;
}
-bool ChildProcessHost::OnMessageReceived(const IPC::Message& msg) {
- return false;
-}
-
-void ChildProcessHost::OnChannelConnected(int32 peer_pid) {
-}
-
-void ChildProcessHost::OnChannelError() {
-}
-
bool ChildProcessHost::Send(IPC::Message* message) {
if (!channel_.get()) {
delete message;
@@ -185,7 +178,7 @@ bool ChildProcessHost::Send(IPC::Message* message) {
return channel_->Send(message);
}
-void ChildProcessHost::OnAllocateSharedMemory(
+void ChildProcessHost::AllocateSharedMemory(
uint32 buffer_size, base::ProcessHandle child_process_handle,
base::SharedMemoryHandle* shared_memory_handle) {
base::SharedMemory shared_buf;
@@ -215,35 +208,7 @@ int ChildProcessHost::GenerateChildProcessUniqueId() {
return base::subtle::NoBarrier_AtomicIncrement(&last_unique_child_id, 1);
}
-
-void ChildProcessHost::OnChildDied() {
- delete this;
-}
-
-void ChildProcessHost::OnChildDisconnected() {
- OnChildDied();
-}
-
-void ChildProcessHost::ShutdownStarted() {
-}
-
-ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host)
- : host_(host), peer_handle_(base::kNullProcessHandle) {
-}
-
-ChildProcessHost::ListenerHook::~ListenerHook() {
- base::CloseProcessHandle(peer_handle_);
-}
-
-void ChildProcessHost::ListenerHook::Shutdown() {
- host_ = NULL;
-}
-
-bool ChildProcessHost::ListenerHook::OnMessageReceived(
- const IPC::Message& msg) {
- if (!host_)
- return true;
-
+bool ChildProcessHost::OnMessageReceived(const IPC::Message& msg) {
#ifdef IPC_MESSAGE_LOG_ENABLED
IPC::Logging* logger = IPC::Logging::GetInstance();
if (msg.type() == IPC_LOGGING_ID) {
@@ -256,72 +221,62 @@ bool ChildProcessHost::ListenerHook::OnMessageReceived(
#endif
bool handled = false;
- for (size_t i = 0; i < host_->filters_.size(); ++i) {
- if (host_->filters_[i]->OnMessageReceived(msg)) {
+ for (size_t i = 0; i < filters_.size(); ++i) {
+ if (filters_[i]->OnMessageReceived(msg)) {
handled = true;
break;
}
}
if (!handled) {
- bool msg_is_good = false;
handled = true;
- IPC_BEGIN_MESSAGE_MAP_EX(ListenerHook, msg, msg_is_good)
+ IPC_BEGIN_MESSAGE_MAP(ChildProcessHost, msg)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
OnShutdownRequest)
IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory,
OnAllocateSharedMemory)
IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP_EX()
+ IPC_END_MESSAGE_MAP()
if (!handled)
- handled = host_->OnMessageReceived(msg);
+ handled = delegate_->OnMessageReceived(msg);
}
#ifdef IPC_MESSAGE_LOG_ENABLED
if (logger->Enabled())
- logger->OnPostDispatchMessage(msg, host_->channel_id_);
+ logger->OnPostDispatchMessage(msg, channel_id_);
#endif
return handled;
}
-void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) {
- if (!host_)
- return;
+void ChildProcessHost::OnChannelConnected(int32 peer_pid) {
if (!base::OpenProcessHandle(peer_pid, &peer_handle_)) {
NOTREACHED();
}
- host_->opening_channel_ = false;
- host_->OnChannelConnected(peer_pid);
- for (size_t i = 0; i < host_->filters_.size(); ++i)
- host_->filters_[i]->OnChannelConnected(peer_pid);
+ opening_channel_ = false;
+ delegate_->OnChannelConnected(peer_pid);
+ for (size_t i = 0; i < filters_.size(); ++i)
+ filters_[i]->OnChannelConnected(peer_pid);
}
-void ChildProcessHost::ListenerHook::OnChannelError() {
- if (!host_)
- return;
- host_->opening_channel_ = false;
- host_->OnChannelError();
+void ChildProcessHost::OnChannelError() {
+ opening_channel_ = false;
+ delegate_->OnChannelError();
- for (size_t i = 0; i < host_->filters_.size(); ++i)
- host_->filters_[i]->OnChannelError();
+ for (size_t i = 0; i < filters_.size(); ++i)
+ filters_[i]->OnChannelError();
// This will delete host_, which will also destroy this!
- host_->OnChildDisconnected();
-}
-
-bool ChildProcessHost::ListenerHook::Send(IPC::Message* message) {
- return host_->Send(message);
+ delegate_->OnChildDisconnected();
}
-void ChildProcessHost::ListenerHook::OnAllocateSharedMemory(
+void ChildProcessHost::OnAllocateSharedMemory(
uint32 buffer_size,
base::SharedMemoryHandle* handle) {
- ChildProcessHost::OnAllocateSharedMemory(
- buffer_size, peer_handle_, handle);
+ AllocateSharedMemory(buffer_size, peer_handle_, handle);
}
-void ChildProcessHost::ListenerHook::OnShutdownRequest() {
- if (host_->CanShutdown())
- host_->Send(new ChildProcessMsg_Shutdown());
+void ChildProcessHost::OnShutdownRequest() {
+ if (delegate_->CanShutdown())
+ Send(new ChildProcessMsg_Shutdown());
}
diff --git a/content/common/child_process_host.h b/content/common/child_process_host.h
index be73fa1..7f044f4 100644
--- a/content/common/child_process_host.h
+++ b/content/common/child_process_host.h
@@ -21,12 +21,12 @@
class FilePath;
-namespace IPC {
-class Message;
+namespace content {
+class ChildProcessHostDelegate;
}
// Provides common functionality for hosting a child process and processing IPC
-// messages between the host and the child process. Subclasses are responsible
+// messages between the host and the child process. Users are responsible
// for the actual launching and terminating of the child processes.
class CONTENT_EXPORT ChildProcessHost : public IPC::Channel::Listener,
public IPC::Message::Sender {
@@ -80,6 +80,8 @@ class CONTENT_EXPORT ChildProcessHost : public IPC::Channel::Listener,
// On failure, returns an empty FilePath.
static FilePath GetChildPath(int flags);
+ explicit ChildProcessHost(content::ChildProcessHostDelegate* delegate);
+
// IPC::Message::Sender implementation.
virtual bool Send(IPC::Message* message) OVERRIDE;
@@ -87,7 +89,7 @@ class CONTENT_EXPORT ChildProcessHost : public IPC::Channel::Listener,
void AddFilter(IPC::ChannelProxy::MessageFilter* filter);
// Public and static for reuse by RenderMessageFilter.
- static void OnAllocateSharedMemory(
+ static void AllocateSharedMemory(
uint32 buffer_size, base::ProcessHandle child_process,
base::SharedMemoryHandle* handle);
@@ -104,68 +106,30 @@ class CONTENT_EXPORT ChildProcessHost : public IPC::Channel::Listener,
// but normally this will be used on the IO thread.
static int GenerateChildProcessUniqueId();
- protected:
- ChildProcessHost();
-
- // Derived classes return true if it's ok to shut down the child process.
- virtual bool CanShutdown() = 0;
-
// Send the shutdown message to the child process.
// Does not check if CanShutdown is true.
- virtual void ForceShutdown();
+ void ForceShutdown();
// Creates the IPC channel. Returns true iff it succeeded.
- virtual bool CreateChannel();
-
- // IPC::Channel::Listener implementation:
- virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
- virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
- virtual void OnChannelError() OVERRIDE;
+ bool CreateChannel();
bool opening_channel() { return opening_channel_; }
const std::string& channel_id() { return channel_id_; }
IPC::Channel* channel() { return channel_.get(); }
- // Called when the child process goes away. See OnChildDisconnected().
- virtual void OnChildDied();
-
- // Called when the child process unexpected closes the IPC channel. The
- // default action is to call OnChildDied(). Subclasses might want to override
- // this behavior.
- virtual void OnChildDisconnected();
-
- // Notifies the derived class that we told the child process to kill itself.
- virtual void ShutdownStarted();
-
private:
- // By using an internal class as the IPC::Channel::Listener, we can intercept
- // OnMessageReceived/OnChannelConnected and do our own processing before
- // calling the subclass' implementation.
- class ListenerHook : public IPC::Channel::Listener {
- public:
- explicit ListenerHook(ChildProcessHost* host);
- virtual ~ListenerHook();
-
- void Shutdown();
-
- // IPC::Channel::Listener methods:
- virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
- virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
- virtual void OnChannelError() OVERRIDE;
-
- bool Send(IPC::Message* message);
-
- private:
- void OnShutdownRequest();
- void OnAllocateSharedMemory(uint32 buffer_size,
- base::SharedMemoryHandle* handle);
- ChildProcessHost* host_;
- base::ProcessHandle peer_handle_;
- DISALLOW_COPY_AND_ASSIGN(ListenerHook);
- };
+ // IPC::Channel::Listener methods:
+ virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
+ virtual void OnChannelError() OVERRIDE;
- ListenerHook listener_;
+ // Message handlers:
+ void OnShutdownRequest();
+ void OnAllocateSharedMemory(uint32 buffer_size,
+ base::SharedMemoryHandle* handle);
+ content::ChildProcessHostDelegate* delegate_;
+ base::ProcessHandle peer_handle_;
bool opening_channel_; // True while we're waiting the channel to be opened.
scoped_ptr<IPC::Channel> channel_;
std::string channel_id_;
diff --git a/content/content_common.gypi b/content/content_common.gypi
index b4891f8..a9bdb55 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -29,6 +29,7 @@
],
'sources': [
'public/common/bindings_policy.h',
+ 'public/common/child_process_host_delegate.h',
'public/common/child_process_sandbox_support_linux.h',
'public/common/content_constants.cc',
'public/common/content_constants.h',
diff --git a/content/public/common/child_process_host_delegate.h b/content/public/common/child_process_host_delegate.h
new file mode 100644
index 0000000..7b9cbd1
--- /dev/null
+++ b/content/public/common/child_process_host_delegate.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2011 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.
+
+#ifndef CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_
+#define CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_
+#pragma once
+
+#include <string>
+
+#include "ipc/ipc_channel.h"
+
+namespace content {
+
+// Interface that all users of ChildProcessHost need to provide.
+class ChildProcessHostDelegate : public IPC::Channel::Listener {
+ public:
+ virtual ~ChildProcessHostDelegate() {}
+
+ // Derived classes return true if it's ok to shut down the child process.
+ // Normally they would return true. The exception is if the host is in the
+ // middle of sending a request to the process, in which case the other side
+ // might think it's ok to shutdown, when really it's not.
+ virtual bool CanShutdown() = 0;
+
+ // Notifies the derived class that we told the child process to kill itself.
+ virtual void ShutdownStarted() = 0;
+
+ // Called when the child process unexpected closes the IPC channel. Delegates
+ // would normally delete the object in this case.
+ virtual void OnChildDisconnected() = 0;
+};
+
+}; // namespace content
+
+#endif // CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_