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

Side by Side Diff: chrome/common/child_process_host.cc

Issue 155331: plugins: use OnChannelError to detect when the channel goes away (Closed)
Patch Set: with a fix to a unit test Created 11 years, 5 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
« no previous file with comments | « chrome/common/child_process_host.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/child_process_host.h" 5 #include "chrome/common/child_process_host.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/process_util.h" 10 #include "base/process_util.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 44
45 } // namespace 45 } // namespace
46 46
47 47
48 48
49 ChildProcessHost::ChildProcessHost( 49 ChildProcessHost::ChildProcessHost(
50 ProcessType type, ResourceDispatcherHost* resource_dispatcher_host) 50 ProcessType type, ResourceDispatcherHost* resource_dispatcher_host)
51 : Receiver(type), 51 : Receiver(type),
52 ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)), 52 ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)),
53 resource_dispatcher_host_(resource_dispatcher_host), 53 resource_dispatcher_host_(resource_dispatcher_host),
54 opening_channel_(false), 54 opening_channel_(false) {
55 process_event_(NULL) {
56 Singleton<ChildProcessList>::get()->push_back(this); 55 Singleton<ChildProcessList>::get()->push_back(this);
57 } 56 }
58 57
59 58
60 ChildProcessHost::~ChildProcessHost() { 59 ChildProcessHost::~ChildProcessHost() {
61 Singleton<ChildProcessList>::get()->remove(this); 60 Singleton<ChildProcessList>::get()->remove(this);
62 61
63 resource_dispatcher_host_->CancelRequestsForProcess(GetProcessId()); 62 resource_dispatcher_host_->CancelRequestsForProcess(GetProcessId());
64 63
65 if (handle()) { 64 if (handle())
66 watcher_.StopWatching();
67 ProcessWatcher::EnsureProcessTerminated(handle()); 65 ProcessWatcher::EnsureProcessTerminated(handle());
68
69 #if defined(OS_WIN)
70 // Above call took ownership, so don't want WaitableEvent to assert because
71 // the handle isn't valid anymore.
72 process_event_->Release();
73 #endif
74 }
75 } 66 }
76 67
77 bool ChildProcessHost::CreateChannel() { 68 bool ChildProcessHost::CreateChannel() {
78 channel_id_ = GenerateRandomChannelID(this); 69 channel_id_ = GenerateRandomChannelID(this);
79 channel_.reset(new IPC::Channel( 70 channel_.reset(new IPC::Channel(
80 channel_id_, IPC::Channel::MODE_SERVER, &listener_)); 71 channel_id_, IPC::Channel::MODE_SERVER, &listener_));
81 if (!channel_->Connect()) 72 if (!channel_->Connect())
82 return false; 73 return false;
83 74
84 opening_channel_ = true; 75 opening_channel_ = true;
85 76
86 return true; 77 return true;
87 } 78 }
88 79
89 void ChildProcessHost::SetHandle(base::ProcessHandle process) { 80 void ChildProcessHost::SetHandle(base::ProcessHandle process) {
90 #if defined(OS_WIN)
91 process_event_.reset(new base::WaitableEvent(process));
92
93 DCHECK(!handle()); 81 DCHECK(!handle());
94 set_handle(process); 82 set_handle(process);
95 watcher_.StartWatching(process_event_.get(), this);
96 #endif
97 } 83 }
98 84
99 void ChildProcessHost::InstanceCreated() { 85 void ChildProcessHost::InstanceCreated() {
100 Notify(NotificationType::CHILD_INSTANCE_CREATED); 86 Notify(NotificationType::CHILD_INSTANCE_CREATED);
101 } 87 }
102 88
103 bool ChildProcessHost::Send(IPC::Message* msg) { 89 bool ChildProcessHost::Send(IPC::Message* msg) {
104 if (!channel_.get()) { 90 if (!channel_.get()) {
105 delete msg; 91 delete msg;
106 return false; 92 return false;
107 } 93 }
108 return channel_->Send(msg); 94 return channel_->Send(msg);
109 } 95 }
110 96
111 void ChildProcessHost::Notify(NotificationType type) { 97 void ChildProcessHost::Notify(NotificationType type) {
112 resource_dispatcher_host_->ui_loop()->PostTask( 98 resource_dispatcher_host_->ui_loop()->PostTask(
113 FROM_HERE, new ChildNotificationTask(type, this)); 99 FROM_HERE, new ChildNotificationTask(type, this));
114 } 100 }
115 101
116 void ChildProcessHost::OnWaitableEventSignaled(base::WaitableEvent *event) { 102 void ChildProcessHost::OnChildDied() {
117 #if defined(OS_WIN)
118 HANDLE object = event->handle();
119 DCHECK(handle()); 103 DCHECK(handle());
120 DCHECK_EQ(object, handle());
121 104
122 bool did_crash = base::DidProcessCrash(NULL, object); 105 bool did_crash = base::DidProcessCrash(NULL, handle());
123 if (did_crash) { 106 if (did_crash) {
124 // Report that this child process crashed. 107 // Report that this child process crashed.
125 Notify(NotificationType::CHILD_PROCESS_CRASHED); 108 Notify(NotificationType::CHILD_PROCESS_CRASHED);
126 } 109 }
127 // Notify in the main loop of the disconnection. 110 // Notify in the main loop of the disconnection.
128 Notify(NotificationType::CHILD_PROCESS_HOST_DISCONNECTED); 111 Notify(NotificationType::CHILD_PROCESS_HOST_DISCONNECTED);
129 #endif 112
113 // On POSIX, once we've called DidProcessCrash, handle() is no longer
114 // valid. Ensure the destructor doesn't try to use it.
115 set_handle(NULL);
130 116
131 delete this; 117 delete this;
132 } 118 }
133 119
134 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host) 120 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host)
135 : host_(host) { 121 : host_(host) {
136 } 122 }
137 123
138 void ChildProcessHost::ListenerHook::OnMessageReceived( 124 void ChildProcessHost::ListenerHook::OnMessageReceived(
139 const IPC::Message& msg) { 125 const IPC::Message& msg) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 host_->OnChannelConnected(peer_pid); 164 host_->OnChannelConnected(peer_pid);
179 host_->Send(new PluginProcessMsg_AskBeforeShutdown()); 165 host_->Send(new PluginProcessMsg_AskBeforeShutdown());
180 166
181 // Notify in the main loop of the connection. 167 // Notify in the main loop of the connection.
182 host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED); 168 host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED);
183 } 169 }
184 170
185 void ChildProcessHost::ListenerHook::OnChannelError() { 171 void ChildProcessHost::ListenerHook::OnChannelError() {
186 host_->opening_channel_ = false; 172 host_->opening_channel_ = false;
187 host_->OnChannelError(); 173 host_->OnChannelError();
174
175 // This will delete host_, which will also destroy this!
176 host_->OnChildDied();
188 } 177 }
189 178
190 179
191 ChildProcessHost::Iterator::Iterator() : all_(true) { 180 ChildProcessHost::Iterator::Iterator() : all_(true) {
192 DCHECK(MessageLoop::current() == 181 DCHECK(MessageLoop::current() ==
193 ChromeThread::GetMessageLoop(ChromeThread::IO)) << 182 ChromeThread::GetMessageLoop(ChromeThread::IO)) <<
194 "ChildProcessInfo::Iterator must be used on the IO thread."; 183 "ChildProcessInfo::Iterator must be used on the IO thread.";
195 iterator_ = Singleton<ChildProcessList>::get()->begin(); 184 iterator_ = Singleton<ChildProcessList>::get()->begin();
196 } 185 }
197 186
(...skipping 18 matching lines...) Expand all
216 205
217 return *iterator_; 206 return *iterator_;
218 } while (true); 207 } while (true);
219 208
220 return NULL; 209 return NULL;
221 } 210 }
222 211
223 bool ChildProcessHost::Iterator::Done() { 212 bool ChildProcessHost::Iterator::Done() {
224 return iterator_ == Singleton<ChildProcessList>::get()->end(); 213 return iterator_ == Singleton<ChildProcessList>::get()->end();
225 } 214 }
OLDNEW
« no previous file with comments | « chrome/common/child_process_host.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698