1 : // Copyright (c) 2009 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 "chrome/common/child_thread.h"
6 :
7 : #include "base/string_util.h"
8 : #include "base/command_line.h"
9 : #include "chrome/common/child_process.h"
10 : #include "chrome/common/chrome_switches.h"
11 : #include "chrome/common/ipc_logging.h"
12 :
13 : // V8 needs a 1MB stack size.
14 : const size_t ChildThread::kV8StackSize = 1024 * 1024;
15 :
16 1 : ChildThread::ChildThread(Thread::Options options)
17 : : Thread("Chrome_ChildThread"),
18 1 : owner_loop_(MessageLoop::current()),
19 : options_(options),
20 2 : check_with_browser_before_shutdown_(false) {
21 1 : DCHECK(owner_loop_);
22 : channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValue(
23 1 : switches::kProcessChannelID);
24 1 : }
25 :
26 0 : ChildThread::~ChildThread() {
27 0 : }
28 :
29 1 : bool ChildThread::Run() {
30 1 : return StartWithOptions(options_);
31 : }
32 :
33 0 : void ChildThread::OnChannelError() {
34 0 : owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
35 0 : }
36 :
37 0 : bool ChildThread::Send(IPC::Message* msg) {
38 0 : if (!channel_.get()) {
39 0 : delete msg;
40 0 : return false;
41 : }
42 :
43 0 : return channel_->Send(msg);
44 : }
45 :
46 0 : void ChildThread::AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
47 0 : DCHECK(MessageLoop::current() == message_loop());
48 :
49 0 : router_.AddRoute(routing_id, listener);
50 0 : }
51 :
52 0 : void ChildThread::RemoveRoute(int32 routing_id) {
53 0 : DCHECK(MessageLoop::current() == message_loop());
54 :
55 0 : router_.RemoveRoute(routing_id);
56 0 : }
57 :
58 0 : void ChildThread::OnMessageReceived(const IPC::Message& msg) {
59 0 : if (msg.routing_id() == MSG_ROUTING_CONTROL) {
60 0 : OnControlMessageReceived(msg);
61 : } else {
62 0 : router_.OnMessageReceived(msg);
63 : }
64 0 : }
65 :
66 2 : ChildThread* ChildThread::current() {
67 2 : return ChildProcess::current()->child_thread();
68 : }
69 :
70 1 : void ChildThread::Init() {
71 : channel_.reset(new IPC::Channel(channel_name_,
72 : IPC::Channel::MODE_CLIENT,
73 1 : this));
74 :
75 : #ifdef IPC_MESSAGE_LOG_ENABLED
76 1 : IPC::Logging::current()->SetIPCSender(this);
77 : #endif
78 1 : }
79 :
80 0 : void ChildThread::CleanUp() {
81 : #ifdef IPC_MESSAGE_LOG_ENABLED
82 0 : IPC::Logging::current()->SetIPCSender(NULL);
83 : #endif
84 : // Need to destruct the SyncChannel to the browser before we go away because
85 : // it caches a pointer to this thread.
86 0 : channel_.reset();
87 0 : }
88 :
89 0 : void ChildThread::OnProcessFinalRelease() {
90 0 : if (!check_with_browser_before_shutdown_) {
91 0 : owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
92 0 : return;
93 : }
94 : }
|