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

Unified Diff: base/mp/mp_child_thread.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_thread.h ('k') | base/mp/mp_messages.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/mp/mp_child_thread.cc
===================================================================
--- base/mp/mp_child_thread.cc (revision 0)
+++ base/mp/mp_child_thread.cc (revision 0)
@@ -0,0 +1,153 @@
+// 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_thread.h"
+
+#include "base/string_util.h"
+#include "base/command_line.h"
+#include "base/mp/mp_child_process.h"
+#include "base/mp/mp_messages.h"
+#include "ipc/ipc_logging.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_sync_message_filter.h"
+#include "ipc/ipc_switches.h"
+
+namespace base {
+
+MpChildThread::MpChildThread() {
+ channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kProcessChannelID);
+ Init();
+}
+
+MpChildThread::MpChildThread(const std::string& channel_name)
+ : channel_name_(channel_name) {
+ Init();
+}
+
+void MpChildThread::Init() {
+ check_with_parent_before_shutdown_ = false;
+ on_channel_error_called_ = false;
+ message_loop_ = MessageLoop::current();
+
+ channel_.reset(new IPC::SyncChannel(channel_name_,
+ IPC::Channel::MODE_CLIENT, this, NULL,
+ MpChildProcess::current()->io_message_loop(), true,
+ MpChildProcess::current()->GetShutDownEvent()));
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging::current()->SetIPCSender(this);
+#endif
+
+ sync_message_filter_ =
+ new IPC::SyncMessageFilter(MpChildProcess::current()->GetShutDownEvent());
+ channel_->AddFilter(sync_message_filter_.get());
+}
+
+MpChildThread::~MpChildThread() {
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging::current()->SetIPCSender(NULL);
+#endif
+
+ channel_->RemoveFilter(sync_message_filter_.get());
+
+ // The ChannelProxy object caches a pointer to the IPC thread, so need to
+ // reset it as it's not guaranteed to outlive this object.
+ // NOTE: this also has the side-effect of not closing the main IPC channel to
+ // the browser process. This is needed because this is the signal that the
+ // browser uses to know that this process has died, so we need it to be alive
+ // until this process is shut down, and the OS closes the handle
+ // automatically. We used to watch the object handle on Windows to do this,
+ // but it wasn't possible to do so on POSIX.
+ channel_->ClearIPCMessageLoop();
+}
+
+void MpChildThread::OnChannelError() {
+ set_on_channel_error_called(true);
+ MessageLoop::current()->Quit();
+}
+
+bool MpChildThread::Send(IPC::Message* msg) {
+ if (!channel_.get()) {
+ delete msg;
+ return false;
+ }
+
+ return channel_->Send(msg);
+}
+
+void MpChildThread::AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
+ DCHECK(MessageLoop::current() == message_loop());
+
+ router_.AddRoute(routing_id, listener);
+}
+
+void MpChildThread::RemoveRoute(int32 routing_id) {
+ DCHECK(MessageLoop::current() == message_loop());
+
+ router_.RemoveRoute(routing_id);
+}
+
+IPC::Channel::Listener* MpChildThread::ResolveRoute(int32 routing_id) {
+ DCHECK(MessageLoop::current() == message_loop());
+
+ return router_.ResolveRoute(routing_id);
+}
+
+void MpChildThread::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(MpChildThread, msg)
+ IPC_MESSAGE_HANDLER(MultiProcessMsg_AskBeforeShutdown, OnAskBeforeShutdown)
+ IPC_MESSAGE_HANDLER(MultiProcessMsg_Shutdown, OnShutdown)
+#if defined(IPC_MESSAGE_LOG_ENABLED)
+ IPC_MESSAGE_HANDLER(MultiProcessMsg_SetIPCLoggingEnabled,
+ OnSetIPCLoggingEnabled)
+#endif
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+
+ if (handled)
+ return;
+
+ if (msg.routing_id() == MSG_ROUTING_CONTROL) {
+ OnControlMessageReceived(msg);
+ } else {
+ router_.OnMessageReceived(msg);
+ }
+}
+
+void MpChildThread::OnAskBeforeShutdown() {
+ check_with_parent_before_shutdown_ = true;
+}
+
+void MpChildThread::OnShutdown() {
+ MessageLoop::current()->Quit();
+}
+
+#if defined(IPC_MESSAGE_LOG_ENABLED)
+void MpChildThread::OnSetIPCLoggingEnabled(bool enable) {
+ if (enable)
+ IPC::Logging::current()->Enable();
+ else
+ IPC::Logging::current()->Disable();
+}
+#endif // IPC_MESSAGE_LOG_ENABLED
+
+MpChildThread* MpChildThread::current() {
+ return MpChildProcess::current()->main_thread();
+}
+
+void MpChildThread::OnProcessFinalRelease() {
+ if (on_channel_error_called_ || !check_with_parent_before_shutdown_) {
+ MessageLoop::current()->Quit();
+ return;
+ }
+
+ // The child process shutdown sequence is a request response based mechanism,
+ // where we send out an initial feeler request to the child process host
+ // instance in the browser to verify if it's ok to shutdown the child process.
+ // The browser then sends back a response if it's ok to shutdown.
+ Send(new MultiProcessHostMsg_ShutdownRequest);
+}
+
+} // namespace base
« no previous file with comments | « base/mp/mp_child_thread.h ('k') | base/mp/mp_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698