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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/mp/mp_child_thread.h ('k') | base/mp/mp_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/mp/mp_child_thread.h"
6
7 #include "base/string_util.h"
8 #include "base/command_line.h"
9 #include "base/mp/mp_child_process.h"
10 #include "base/mp/mp_messages.h"
11 #include "ipc/ipc_logging.h"
12 #include "ipc/ipc_message.h"
13 #include "ipc/ipc_sync_message_filter.h"
14 #include "ipc/ipc_switches.h"
15
16 namespace base {
17
18 MpChildThread::MpChildThread() {
19 channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
20 switches::kProcessChannelID);
21 Init();
22 }
23
24 MpChildThread::MpChildThread(const std::string& channel_name)
25 : channel_name_(channel_name) {
26 Init();
27 }
28
29 void MpChildThread::Init() {
30 check_with_parent_before_shutdown_ = false;
31 on_channel_error_called_ = false;
32 message_loop_ = MessageLoop::current();
33
34 channel_.reset(new IPC::SyncChannel(channel_name_,
35 IPC::Channel::MODE_CLIENT, this, NULL,
36 MpChildProcess::current()->io_message_loop(), true,
37 MpChildProcess::current()->GetShutDownEvent()));
38 #ifdef IPC_MESSAGE_LOG_ENABLED
39 IPC::Logging::current()->SetIPCSender(this);
40 #endif
41
42 sync_message_filter_ =
43 new IPC::SyncMessageFilter(MpChildProcess::current()->GetShutDownEvent());
44 channel_->AddFilter(sync_message_filter_.get());
45 }
46
47 MpChildThread::~MpChildThread() {
48 #ifdef IPC_MESSAGE_LOG_ENABLED
49 IPC::Logging::current()->SetIPCSender(NULL);
50 #endif
51
52 channel_->RemoveFilter(sync_message_filter_.get());
53
54 // The ChannelProxy object caches a pointer to the IPC thread, so need to
55 // reset it as it's not guaranteed to outlive this object.
56 // NOTE: this also has the side-effect of not closing the main IPC channel to
57 // the browser process. This is needed because this is the signal that the
58 // browser uses to know that this process has died, so we need it to be alive
59 // until this process is shut down, and the OS closes the handle
60 // automatically. We used to watch the object handle on Windows to do this,
61 // but it wasn't possible to do so on POSIX.
62 channel_->ClearIPCMessageLoop();
63 }
64
65 void MpChildThread::OnChannelError() {
66 set_on_channel_error_called(true);
67 MessageLoop::current()->Quit();
68 }
69
70 bool MpChildThread::Send(IPC::Message* msg) {
71 if (!channel_.get()) {
72 delete msg;
73 return false;
74 }
75
76 return channel_->Send(msg);
77 }
78
79 void MpChildThread::AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
80 DCHECK(MessageLoop::current() == message_loop());
81
82 router_.AddRoute(routing_id, listener);
83 }
84
85 void MpChildThread::RemoveRoute(int32 routing_id) {
86 DCHECK(MessageLoop::current() == message_loop());
87
88 router_.RemoveRoute(routing_id);
89 }
90
91 IPC::Channel::Listener* MpChildThread::ResolveRoute(int32 routing_id) {
92 DCHECK(MessageLoop::current() == message_loop());
93
94 return router_.ResolveRoute(routing_id);
95 }
96
97 void MpChildThread::OnMessageReceived(const IPC::Message& msg) {
98 bool handled = true;
99 IPC_BEGIN_MESSAGE_MAP(MpChildThread, msg)
100 IPC_MESSAGE_HANDLER(MultiProcessMsg_AskBeforeShutdown, OnAskBeforeShutdown)
101 IPC_MESSAGE_HANDLER(MultiProcessMsg_Shutdown, OnShutdown)
102 #if defined(IPC_MESSAGE_LOG_ENABLED)
103 IPC_MESSAGE_HANDLER(MultiProcessMsg_SetIPCLoggingEnabled,
104 OnSetIPCLoggingEnabled)
105 #endif
106 IPC_MESSAGE_UNHANDLED(handled = false)
107 IPC_END_MESSAGE_MAP()
108
109 if (handled)
110 return;
111
112 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
113 OnControlMessageReceived(msg);
114 } else {
115 router_.OnMessageReceived(msg);
116 }
117 }
118
119 void MpChildThread::OnAskBeforeShutdown() {
120 check_with_parent_before_shutdown_ = true;
121 }
122
123 void MpChildThread::OnShutdown() {
124 MessageLoop::current()->Quit();
125 }
126
127 #if defined(IPC_MESSAGE_LOG_ENABLED)
128 void MpChildThread::OnSetIPCLoggingEnabled(bool enable) {
129 if (enable)
130 IPC::Logging::current()->Enable();
131 else
132 IPC::Logging::current()->Disable();
133 }
134 #endif // IPC_MESSAGE_LOG_ENABLED
135
136 MpChildThread* MpChildThread::current() {
137 return MpChildProcess::current()->main_thread();
138 }
139
140 void MpChildThread::OnProcessFinalRelease() {
141 if (on_channel_error_called_ || !check_with_parent_before_shutdown_) {
142 MessageLoop::current()->Quit();
143 return;
144 }
145
146 // The child process shutdown sequence is a request response based mechanism,
147 // where we send out an initial feeler request to the child process host
148 // instance in the browser to verify if it's ok to shutdown the child process.
149 // The browser then sends back a response if it's ok to shutdown.
150 Send(new MultiProcessHostMsg_ShutdownRequest);
151 }
152
153 } // namespace base
OLDNEW
« 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