-
Notifications
You must be signed in to change notification settings - Fork 2k
/
child_thread.cc
143 lines (118 loc) · 3.96 KB
/
child_thread.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Copyright (c) 2009 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/common/child_thread.h"
#include "base/string_util.h"
#include "base/command_line.h"
#include "chrome/common/child_process.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/ipc_logging.h"
#ifndef CHROMIUM_MOZILLA_BUILD
#include "chrome/common/plugin_messages.h"
#include "webkit/glue/webkit_glue.h"
#endif
// V8 needs a 1MB stack size.
const size_t ChildThread::kV8StackSize = 1024 * 1024;
ChildThread::ChildThread(Thread::Options options)
: Thread("Chrome_ChildThread"),
owner_loop_(MessageLoop::current()),
options_(options),
check_with_browser_before_shutdown_(false) {
DCHECK(owner_loop_);
channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValue(
switches::kProcessChannelID);
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserAgent)) {
#ifndef CHROMIUM_MOZILLA_BUILD
webkit_glue::SetUserAgent(WideToUTF8(
CommandLine::ForCurrentProcess()->GetSwitchValue(
switches::kUserAgent)));
#endif
}
}
ChildThread::~ChildThread() {
}
bool ChildThread::Run() {
return StartWithOptions(options_);
}
void ChildThread::OnChannelError() {
owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
}
bool ChildThread::Send(IPC::Message* msg) {
if (!channel_.get()) {
delete msg;
return false;
}
return channel_->Send(msg);
}
void ChildThread::AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
DCHECK(MessageLoop::current() == message_loop());
router_.AddRoute(routing_id, listener);
}
void ChildThread::RemoveRoute(int32 routing_id) {
DCHECK(MessageLoop::current() == message_loop());
router_.RemoveRoute(routing_id);
}
void ChildThread::OnMessageReceived(const IPC::Message& msg) {
#ifndef CHROMIUM_MOZILLA_BUILD
// Resource responses are sent to the resource dispatcher.
if (resource_dispatcher_->OnMessageReceived(msg))
return;
if (msg.type() == PluginProcessMsg_AskBeforeShutdown::ID) {
check_with_browser_before_shutdown_ = true;
return;
}
if (msg.type() == PluginProcessMsg_Shutdown::ID) {
owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
return;
}
#endif
if (msg.routing_id() == MSG_ROUTING_CONTROL) {
OnControlMessageReceived(msg);
} else {
router_.OnMessageReceived(msg);
}
}
ChildThread* ChildThread::current() {
return ChildProcess::current()->child_thread();
}
void ChildThread::Init() {
#ifndef CHROMIUM_MOZILLA_BUILD
channel_.reset(new IPC::SyncChannel(channel_name_,
IPC::Channel::MODE_CLIENT, this, NULL, owner_loop_, true,
ChildProcess::current()->GetShutDownEvent()));
#else
channel_.reset(new IPC::Channel(channel_name_,
IPC::Channel::MODE_CLIENT,
this));
#endif
#ifdef IPC_MESSAGE_LOG_ENABLED
IPC::Logging::current()->SetIPCSender(this);
#endif
#ifndef CHROMIUM_MOZILLA_BUILD
resource_dispatcher_.reset(new ResourceDispatcher(this));
#endif
}
void ChildThread::CleanUp() {
#ifdef IPC_MESSAGE_LOG_ENABLED
IPC::Logging::current()->SetIPCSender(NULL);
#endif
// Need to destruct the SyncChannel to the browser before we go away because
// it caches a pointer to this thread.
channel_.reset();
#ifndef CHROMIUM_MOZILLA_BUILD
resource_dispatcher_.reset();
#endif
}
void ChildThread::OnProcessFinalRelease() {
if (!check_with_browser_before_shutdown_) {
owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
return;
}
#ifndef CHROMIUM_MOZILLA_BUILD
// 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 PluginProcessHostMsg_ShutdownRequest);
#endif
}