summaryrefslogtreecommitdiffstats
path: root/content/browser/browser_child_process_host.cc
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-20 06:29:23 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-20 06:29:23 +0000
commit3b0032a7abc9cc9350253d4f66dcd9a367e206ab (patch)
tree3c7ae09453fe79f47ed7e0b5095aef5518bb4e95 /content/browser/browser_child_process_host.cc
parent1027ebc3ec3fbb9fd44112e42bb06906895712bb (diff)
downloadchromium_src-3b0032a7abc9cc9350253d4f66dcd9a367e206ab.zip
chromium_src-3b0032a7abc9cc9350253d4f66dcd9a367e206ab.tar.gz
chromium_src-3b0032a7abc9cc9350253d4f66dcd9a367e206ab.tar.bz2
Add a Content API around BrowserChildProcessHost, similar to what was done with ChildProcessHost. Now classes like PluginProcessHost don't derive from it, but instead use composition.
I've also moved the iterator class into its own file in the public directory. Since classes don't derive from BrowserChildProcessHost and so can't static_cast from it, I added a template helper that does this. BUG=98716 Review URL: https://chromiumcodereview.appspot.com/9150017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118415 0039d316-1c4b-4281-b951-d872f2087c98
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();
}