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

Side by Side Diff: content/browser/worker_host/worker_service.cc

Issue 8399007: Removing dedicated worker-related IPC codei (first round). (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebased Created 9 years, 1 month 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "content/browser/worker_host/worker_service.h" 5 #include "content/browser/worker_host/worker_service.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 const ViewHostMsg_CreateWorker_Params& params, 77 const ViewHostMsg_CreateWorker_Params& params,
78 int route_id, 78 int route_id,
79 WorkerMessageFilter* filter, 79 WorkerMessageFilter* filter,
80 const content::ResourceContext& resource_context) { 80 const content::ResourceContext& resource_context) {
81 // Generate a unique route id for the browser-worker communication that's 81 // Generate a unique route id for the browser-worker communication that's
82 // unique among all worker processes. That way when the worker process sends 82 // unique among all worker processes. That way when the worker process sends
83 // a wrapped IPC message through us, we know which WorkerProcessHost to give 83 // a wrapped IPC message through us, we know which WorkerProcessHost to give
84 // it to. 84 // it to.
85 WorkerProcessHost::WorkerInstance instance( 85 WorkerProcessHost::WorkerInstance instance(
86 params.url, 86 params.url,
87 params.is_shared,
88 params.name, 87 params.name,
89 next_worker_route_id(), 88 next_worker_route_id(),
90 params.is_shared ? 0 : filter->render_process_id(), 89 0,
91 params.is_shared ? 0 : params.parent_appcache_host_id, 90 params.script_resource_appcache_id,
92 params.is_shared ? params.script_resource_appcache_id : 0,
93 &resource_context); 91 &resource_context);
94 instance.AddFilter(filter, route_id); 92 instance.AddFilter(filter, route_id);
95 instance.worker_document_set()->Add( 93 instance.worker_document_set()->Add(
96 filter, params.document_id, filter->render_process_id(), 94 filter, params.document_id, filter->render_process_id(),
97 params.render_view_route_id); 95 params.render_view_route_id);
98 96
99 CreateWorkerFromInstance(instance); 97 CreateWorkerFromInstance(instance);
100 } 98 }
101 99
102 void WorkerService::LookupSharedWorker( 100 void WorkerService::LookupSharedWorker(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // TODO(atwilson): This won't work if the message is from a worker process. 132 // TODO(atwilson): This won't work if the message is from a worker process.
135 // We don't support that yet though (this message is only sent from 133 // We don't support that yet though (this message is only sent from
136 // renderers) but when we do, we'll need to add code to pass in the current 134 // renderers) but when we do, we'll need to add code to pass in the current
137 // worker's document set for nested workers. 135 // worker's document set for nested workers.
138 instance->worker_document_set()->Add( 136 instance->worker_document_set()->Add(
139 filter, params.document_id, filter->render_process_id(), 137 filter, params.document_id, filter->render_process_id(),
140 params.render_view_route_id); 138 params.render_view_route_id);
141 } 139 }
142 } 140 }
143 141
144 void WorkerService::CancelCreateDedicatedWorker( 142 void WorkerService::CancelCreateDedicatedWorker(
jam 2011/10/26 22:25:38 i guess this is second round?
145 int route_id, 143 int route_id,
146 WorkerMessageFilter* filter) { 144 WorkerMessageFilter* filter) {
147 for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin();
148 i != queued_workers_.end(); ++i) {
149 if (i->HasFilter(filter, route_id)) {
150 DCHECK(!i->shared());
151 queued_workers_.erase(i);
152 return;
153 }
154 }
155 145
156 // There could be a race condition where the WebWorkerProxy told us to cancel 146 NOTREACHED();
157 // the worker right as we sent it a message say it's been created. Look at
158 // the running workers.
159 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
160 !iter.Done(); ++iter) {
161 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
162 for (WorkerProcessHost::Instances::const_iterator instance =
163 worker->instances().begin();
164 instance != worker->instances().end(); ++instance) {
165 if (instance->HasFilter(filter, route_id)) {
166 // Fake a worker destroyed message so that WorkerProcessHost cleans up
167 // properly.
168 WorkerMsg_TerminateWorkerContext message(route_id);
169 ForwardToWorker(message, filter);
170 return;
171 }
172 }
173 }
174
175 DCHECK(false) << "Couldn't find worker to cancel";
176 } 147 }
177 148
178 void WorkerService::ForwardToWorker(const IPC::Message& message, 149 void WorkerService::ForwardToWorker(const IPC::Message& message,
179 WorkerMessageFilter* filter) { 150 WorkerMessageFilter* filter) {
180 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); 151 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
181 !iter.Done(); ++iter) { 152 !iter.Done(); ++iter) {
182 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); 153 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
183 if (worker->FilterMessage(message, filter)) 154 if (worker->FilterMessage(message, filter))
184 return; 155 return;
185 } 156 }
186 157
187 // TODO(jabdelmalek): tell filter that callee is gone 158 // TODO(jabdelmalek): tell filter that callee is gone
188 } 159 }
189 160
190 void WorkerService::DocumentDetached(unsigned long long document_id, 161 void WorkerService::DocumentDetached(unsigned long long document_id,
191 WorkerMessageFilter* filter) { 162 WorkerMessageFilter* filter) {
192 // Any associated shared workers can be shut down. 163 // Any associated shared workers can be shut down.
193 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); 164 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
194 !iter.Done(); ++iter) { 165 !iter.Done(); ++iter) {
195 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); 166 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
196 worker->DocumentDetached(filter, document_id); 167 worker->DocumentDetached(filter, document_id);
197 } 168 }
198 169
199 // Remove any queued shared workers for this document. 170 // Remove any queued shared workers for this document.
200 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); 171 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin();
201 iter != queued_workers_.end();) { 172 iter != queued_workers_.end();) {
202 if (iter->shared()) { 173
203 iter->worker_document_set()->Remove(filter, document_id); 174 iter->worker_document_set()->Remove(filter, document_id);
204 if (iter->worker_document_set()->IsEmpty()) { 175 if (iter->worker_document_set()->IsEmpty()) {
205 iter = queued_workers_.erase(iter); 176 iter = queued_workers_.erase(iter);
206 continue; 177 continue;
207 }
208 } 178 }
209 ++iter; 179 ++iter;
210 } 180 }
211 181
212 // Remove the document from any pending shared workers. 182 // Remove the document from any pending shared workers.
213 for (WorkerProcessHost::Instances::iterator iter = 183 for (WorkerProcessHost::Instances::iterator iter =
214 pending_shared_workers_.begin(); 184 pending_shared_workers_.begin();
215 iter != pending_shared_workers_.end(); ) { 185 iter != pending_shared_workers_.end(); ) {
216 iter->worker_document_set()->Remove(filter, document_id); 186 iter->worker_document_set()->Remove(filter, document_id);
217 if (iter->worker_document_set()->IsEmpty()) { 187 if (iter->worker_document_set()->IsEmpty()) {
(...skipping 19 matching lines...) Expand all
237 worker = GetProcessForDomain(instance.url()); 207 worker = GetProcessForDomain(instance.url());
238 } else { // One process per worker. 208 } else { // One process per worker.
239 if (!CanCreateWorkerProcess(instance)) { 209 if (!CanCreateWorkerProcess(instance)) {
240 queued_workers_.push_back(instance); 210 queued_workers_.push_back(instance);
241 return true; 211 return true;
242 } 212 }
243 } 213 }
244 214
245 // Check to see if this shared worker is already running (two pages may have 215 // Check to see if this shared worker is already running (two pages may have
246 // tried to start up the worker simultaneously). 216 // tried to start up the worker simultaneously).
247 if (instance.shared()) { 217 // See if a worker with this name already exists.
248 // See if a worker with this name already exists. 218 WorkerProcessHost::WorkerInstance* existing_instance =
249 WorkerProcessHost::WorkerInstance* existing_instance = 219 FindSharedWorkerInstance(
250 FindSharedWorkerInstance( 220 instance.url(), instance.name(), instance.resource_context());
251 instance.url(), instance.name(), instance.resource_context()); 221 WorkerProcessHost::WorkerInstance::FilterInfo filter_info =
252 WorkerProcessHost::WorkerInstance::FilterInfo filter_info = 222 instance.GetFilter();
253 instance.GetFilter(); 223 // If this worker is already running, no need to create a new copy. Just
254 // If this worker is already running, no need to create a new copy. Just 224 // inform the caller that the worker has been created.
255 // inform the caller that the worker has been created. 225 if (existing_instance) {
256 if (existing_instance) { 226 // Walk the worker's filter list to see if this client is listed. If not,
257 // Walk the worker's filter list to see if this client is listed. If not, 227 // then it means that the worker started by the client already exited so
258 // then it means that the worker started by the client already exited so 228 // we should not attach to this new one (http://crbug.com/29243).
259 // we should not attach to this new one (http://crbug.com/29243). 229 if (!existing_instance->HasFilter(filter_info.first, filter_info.second))
260 if (!existing_instance->HasFilter(filter_info.first, filter_info.second)) 230 return false;
261 return false; 231 filter_info.first->Send(new ViewMsg_WorkerCreated(filter_info.second));
262 filter_info.first->Send(new ViewMsg_WorkerCreated(filter_info.second)); 232 return true;
263 return true; 233 }
264 }
265 234
266 // Look to see if there's a pending instance. 235 // Look to see if there's a pending instance.
267 WorkerProcessHost::WorkerInstance* pending = FindPendingInstance( 236 WorkerProcessHost::WorkerInstance* pending = FindPendingInstance(
268 instance.url(), instance.name(), instance.resource_context()); 237 instance.url(), instance.name(), instance.resource_context());
269 // If there's no instance *and* no pending instance (or there is a pending 238 // If there's no instance *and* no pending instance (or there is a pending
270 // instance but it does not contain our filter info), then it means the 239 // instance but it does not contain our filter info), then it means the
271 // worker started up and exited already. Log a warning because this should 240 // worker started up and exited already. Log a warning because this should
272 // be a very rare occurrence and is probably a bug, but it *can* happen so 241 // be a very rare occurrence and is probably a bug, but it *can* happen so
273 // handle it gracefully. 242 // handle it gracefully.
274 if (!pending || 243 if (!pending ||
275 !pending->HasFilter(filter_info.first, filter_info.second)) { 244 !pending->HasFilter(filter_info.first, filter_info.second)) {
276 DLOG(WARNING) << "Pending worker already exited"; 245 DLOG(WARNING) << "Pending worker already exited";
277 return false; 246 return false;
278 } 247 }
279 248
280 // Assign the accumulated document set and filter list for this pending 249 // Assign the accumulated document set and filter list for this pending
281 // worker to the new instance. 250 // worker to the new instance.
282 DCHECK(!pending->worker_document_set()->IsEmpty()); 251 DCHECK(!pending->worker_document_set()->IsEmpty());
283 instance.ShareDocumentSet(*pending); 252 instance.ShareDocumentSet(*pending);
284 for (WorkerProcessHost::WorkerInstance::FilterList::const_iterator i = 253 for (WorkerProcessHost::WorkerInstance::FilterList::const_iterator i =
285 pending->filters().begin(); 254 pending->filters().begin();
286 i != pending->filters().end(); ++i) { 255 i != pending->filters().end(); ++i) {
287 instance.AddFilter(i->first, i->second); 256 instance.AddFilter(i->first, i->second);
288 } 257 }
289 RemovePendingInstances( 258 RemovePendingInstances(
290 instance.url(), instance.name(), instance.resource_context()); 259 instance.url(), instance.name(), instance.resource_context());
291 260
292 // Remove any queued instances of this worker and copy over the filter to 261 // Remove any queued instances of this worker and copy over the filter to
293 // this instance. 262 // this instance.
294 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); 263 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin();
295 iter != queued_workers_.end();) { 264 iter != queued_workers_.end();) {
296 if (iter->Matches(instance.url(), instance.name(), 265 if (iter->Matches(instance.url(), instance.name(),
297 instance.resource_context())) { 266 instance.resource_context())) {
298 DCHECK(iter->NumFilters() == 1); 267 DCHECK(iter->NumFilters() == 1);
299 WorkerProcessHost::WorkerInstance::FilterInfo filter_info = 268 WorkerProcessHost::WorkerInstance::FilterInfo filter_info =
300 iter->GetFilter(); 269 iter->GetFilter();
301 instance.AddFilter(filter_info.first, filter_info.second); 270 instance.AddFilter(filter_info.first, filter_info.second);
302 iter = queued_workers_.erase(iter); 271 iter = queued_workers_.erase(iter);
303 } else { 272 } else {
304 ++iter; 273 ++iter;
305 }
306 } 274 }
307 } 275 }
308 276
309 if (!worker) { 277 if (!worker) {
310 WorkerMessageFilter* first_filter = instance.filters().begin()->first; 278 WorkerMessageFilter* first_filter = instance.filters().begin()->first;
311 worker = new WorkerProcessHost( 279 worker = new WorkerProcessHost(
312 instance.resource_context(), 280 instance.resource_context(),
313 first_filter->resource_dispatcher_host()); 281 first_filter->resource_dispatcher_host());
314 // TODO(atwilson): This won't work if the message is from a worker process. 282 // TODO(atwilson): This won't work if the message is from a worker process.
315 // We don't support that yet though (this message is only sent from 283 // We don't support that yet though (this message is only sent from
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 WorkerProcessHost::WorkerInstance* instance = 547 WorkerProcessHost::WorkerInstance* instance =
580 FindPendingInstance(url, name, resource_context); 548 FindPendingInstance(url, name, resource_context);
581 if (instance) 549 if (instance)
582 return instance; 550 return instance;
583 551
584 // No existing pending worker - create a new one. 552 // No existing pending worker - create a new one.
585 WorkerProcessHost::WorkerInstance pending(url, true, name, resource_context); 553 WorkerProcessHost::WorkerInstance pending(url, true, name, resource_context);
586 pending_shared_workers_.push_back(pending); 554 pending_shared_workers_.push_back(pending);
587 return &pending_shared_workers_.back(); 555 return &pending_shared_workers_.back();
588 } 556 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698