summaryrefslogtreecommitdiffstats
path: root/content/browser/browser_child_process_host.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/browser_child_process_host.cc')
-rw-r--r--content/browser/browser_child_process_host.cc141
1 files changed, 72 insertions, 69 deletions
diff --git a/content/browser/browser_child_process_host.cc b/content/browser/browser_child_process_host.cc
index 9bd3b21..fee30a2 100644
--- a/content/browser/browser_child_process_host.cc
+++ b/content/browser/browser_child_process_host.cc
@@ -20,6 +20,7 @@
#include "content/common/child_process_host_impl.h"
#include "content/common/plugin_messages.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_service.h"
@@ -33,31 +34,48 @@
#include "base/bind.h"
#endif
+using content::BrowserChildProcessHostDelegate;
using content::BrowserThread;
+using content::ChildProcessData;
using content::ChildProcessHost;
using content::ChildProcessHostImpl;
namespace {
-typedef std::list<BrowserChildProcessHost*> BrowserChildProcessList;
-static base::LazyInstance<BrowserChildProcessList> g_child_process_list =
- LAZY_INSTANCE_INITIALIZER;
+static base::LazyInstance<BrowserChildProcessHost::BrowserChildProcessList>
+ g_child_process_list = LAZY_INSTANCE_INITIALIZER;
// Helper functions since the child process related notifications happen on the
// UI thread.
void ChildNotificationHelper(int notification_type,
- const content::ChildProcessData& data) {
+ const ChildProcessData& data) {
content::NotificationService::current()->
Notify(notification_type, content::NotificationService::AllSources(),
- content::Details<const content::ChildProcessData>(&data));
+ content::Details<const ChildProcessData>(&data));
}
} // namespace
+namespace content {
+
+BrowserChildProcessHost* BrowserChildProcessHost::Create(
+ ProcessType type,
+ BrowserChildProcessHostDelegate* delegate) {
+ return new ::BrowserChildProcessHost(type, delegate);
+}
+
+} // namespace content
+
+BrowserChildProcessHost::BrowserChildProcessList*
+ BrowserChildProcessHost::GetIterator() {
+ return g_child_process_list.Pointer();
+}
+
BrowserChildProcessHost::BrowserChildProcessHost(
- content::ProcessType type)
+ content::ProcessType type,
+ BrowserChildProcessHostDelegate* delegate)
: data_(type),
- ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)),
+ delegate_(delegate),
#if !defined(OS_WIN)
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
#endif
@@ -77,6 +95,7 @@ BrowserChildProcessHost::~BrowserChildProcessHost() {
// static
void BrowserChildProcessHost::TerminateAll() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// Make a copy since the BrowserChildProcessHost dtor mutates the original
// list.
BrowserChildProcessList copy = g_child_process_list.Get();
@@ -91,9 +110,10 @@ void BrowserChildProcessHost::Launch(
const base::environment_vector& environ,
#endif
CommandLine* cmd_line) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
content::GetContentClient()->browser()->AppendExtraCommandLineSwitches(
- cmd_line, data().id);
+ cmd_line, data_.id);
child_process_.reset(new ChildProcessLauncher(
#if defined(OS_WIN)
@@ -101,13 +121,24 @@ void BrowserChildProcessHost::Launch(
#elif defined(OS_POSIX)
use_zygote,
environ,
- child_process_host()->TakeClientFileDescriptor(),
+ child_process_host_->TakeClientFileDescriptor(),
#endif
cmd_line,
- &client_));
+ this));
}
-base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const {
+const ChildProcessData& BrowserChildProcessHost::GetData() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return data_;
+}
+
+ChildProcessHost* BrowserChildProcessHost::GetHost() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return child_process_host_.get();
+}
+
+base::ProcessHandle BrowserChildProcessHost::GetHandle() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(child_process_.get())
<< "Requesting a child process handle before launching.";
DCHECK(child_process_->GetHandle())
@@ -116,20 +147,24 @@ base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const {
}
void BrowserChildProcessHost::SetName(const string16& name) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
data_.name = name;
}
void BrowserChildProcessHost::SetHandle(base::ProcessHandle handle) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
data_.handle = handle;
}
void BrowserChildProcessHost::ForceShutdown() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
g_child_process_list.Get().remove(this);
child_process_host_->ForceShutdown();
}
void BrowserChildProcessHost::SetTerminateChildOnShutdown(
- bool terminate_on_shutdown) {
+ bool terminate_on_shutdown) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown);
}
@@ -140,23 +175,29 @@ void BrowserChildProcessHost::Notify(int type) {
base::Bind(&ChildNotificationHelper, type, data_));
}
-base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus(
+base::TerminationStatus BrowserChildProcessHost::GetTerminationStatus(
int* exit_code) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (!child_process_.get()) // If the delegate doesn't use Launch() helper.
- return base::GetTerminationStatus(data().handle, exit_code);
+ return base::GetTerminationStatus(data_.handle, exit_code);
return child_process_->GetChildTerminationStatus(exit_code);
}
bool BrowserChildProcessHost::OnMessageReceived(const IPC::Message& message) {
- return false;
+ return delegate_->OnMessageReceived(message);
}
void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) {
Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED);
+ delegate_->OnChannelConnected(peer_pid);
+}
+
+void BrowserChildProcessHost::OnChannelError() {
+ delegate_->OnChannelError();
}
bool BrowserChildProcessHost::CanShutdown() {
- return true;
+ return delegate_->CanShutdown();
}
// Normally a ChildProcessHostDelegate deletes itself from this callback, but at
@@ -167,21 +208,21 @@ bool BrowserChildProcessHost::CanShutdown() {
// may be called twice: once from the actual channel error and once from
// OnWaitableEventSignaled() or the delayed task.
void BrowserChildProcessHost::OnChildDisconnected() {
- DCHECK(data().handle != base::kNullProcessHandle);
+ DCHECK(data_.handle != base::kNullProcessHandle);
int exit_code;
- base::TerminationStatus status = GetChildTerminationStatus(&exit_code);
+ base::TerminationStatus status = GetTerminationStatus(&exit_code);
switch (status) {
case base::TERMINATION_STATUS_PROCESS_CRASHED:
case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: {
- OnProcessCrashed(exit_code);
+ delegate_->OnProcessCrashed(exit_code);
// Report that this child process crashed.
Notify(content::NOTIFICATION_CHILD_PROCESS_CRASHED);
UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed",
- data().type,
+ data_.type,
content::PROCESS_TYPE_MAX);
if (disconnect_was_alive_) {
UMA_HISTOGRAM_ENUMERATION("ChildProcess.CrashedWasAlive",
- data().type,
+ data_.type,
content::PROCESS_TYPE_MAX);
}
break;
@@ -189,11 +230,11 @@ void BrowserChildProcessHost::OnChildDisconnected() {
case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: {
// Report that this child process was killed.
UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed",
- data().type,
+ data_.type,
content::PROCESS_TYPE_MAX);
if (disconnect_was_alive_) {
UMA_HISTOGRAM_ENUMERATION("ChildProcess.KilledWasAlive",
- data().type,
+ data_.type,
content::PROCESS_TYPE_MAX);
}
break;
@@ -203,14 +244,14 @@ void BrowserChildProcessHost::OnChildDisconnected() {
// code.
if (disconnect_was_alive_) {
UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive",
- data().type,
+ data_.type,
content::PROCESS_TYPE_MAX);
break;
}
disconnect_was_alive_ = true;
#if defined(OS_WIN)
child_watcher_.StartWatching(
- new base::WaitableEvent(data().handle), this);
+ new base::WaitableEvent(data_.handle), this);
#else
// On non-Windows platforms, give the child process some time to die after
// disconnecting the channel so that the exit code and termination status
@@ -230,7 +271,7 @@ void BrowserChildProcessHost::OnChildDisconnected() {
break;
}
UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected",
- data().type,
+ data_.type,
content::PROCESS_TYPE_MAX);
// Notify in the main loop of the disconnection.
Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED);
@@ -265,50 +306,12 @@ void BrowserChildProcessHost::ShutdownStarted() {
g_child_process_list.Get().remove(this);
}
-BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host)
- : host_(host) {
-}
-void BrowserChildProcessHost::ClientHook::OnProcessLaunched() {
- if (!host_->child_process_->GetHandle()) {
- delete host_;
+void BrowserChildProcessHost::OnProcessLaunched() {
+ if (!child_process_->GetHandle()) {
+ delete this;
return;
}
- host_->data_.handle = host_->child_process_->GetHandle();
- host_->OnProcessLaunched();
-}
-
-BrowserChildProcessHost::Iterator::Iterator()
- : all_(true), type_(content::PROCESS_TYPE_UNKNOWN) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) <<
- "BrowserChildProcessHost::Iterator must be used on the IO thread.";
- iterator_ = g_child_process_list.Get().begin();
-}
-
-BrowserChildProcessHost::Iterator::Iterator(content::ProcessType type)
- : all_(false), type_(type) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) <<
- "BrowserChildProcessHost::Iterator must be used on the IO thread.";
- iterator_ = g_child_process_list.Get().begin();
- if (!Done() && (*iterator_)->data().type != type_)
- ++(*this);
-}
-
-BrowserChildProcessHost* BrowserChildProcessHost::Iterator::operator++() {
- do {
- ++iterator_;
- if (Done())
- break;
-
- if (!all_ && (*iterator_)->data().type != type_)
- continue;
-
- return *iterator_;
- } while (true);
-
- return NULL;
-}
-
-bool BrowserChildProcessHost::Iterator::Done() {
- return iterator_ == g_child_process_list.Get().end();
+ data_.handle = child_process_->GetHandle();
+ delegate_->OnProcessLaunched();
}