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

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

Issue 10910207: Remove flags for Workers that violate multiple profile and storage isolation assumptions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge with ToT Created 8 years, 3 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_impl.h" 5 #include "content/browser/worker_host/worker_service_impl.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"
11 #include "base/sys_info.h"
12 #include "base/threading/thread.h" 11 #include "base/threading/thread.h"
13 #include "content/browser/debugger/worker_devtools_manager.h" 12 #include "content/browser/debugger/worker_devtools_manager.h"
14 #include "content/browser/worker_host/worker_message_filter.h" 13 #include "content/browser/worker_host/worker_message_filter.h"
15 #include "content/browser/worker_host/worker_process_host.h" 14 #include "content/browser/worker_host/worker_process_host.h"
16 #include "content/common/view_messages.h" 15 #include "content/common/view_messages.h"
17 #include "content/common/worker_messages.h" 16 #include "content/common/worker_messages.h"
18 #include "content/public/browser/child_process_data.h" 17 #include "content/public/browser/child_process_data.h"
19 #include "content/public/browser/resource_context.h" 18 #include "content/public/browser/resource_context.h"
20 #include "content/public/browser/worker_service_observer.h" 19 #include "content/public/browser/worker_service_observer.h"
21 #include "content/public/common/content_switches.h" 20 #include "content/public/common/content_switches.h"
22 #include "content/public/common/process_type.h" 21 #include "content/public/common/process_type.h"
23 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
24 22
25 namespace content { 23 namespace content {
26 24
27 const int WorkerServiceImpl::kMaxWorkerProcessesWhenSharing = 10;
28 const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64; 25 const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64;
29 const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16; 26 const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16;
30 27
31 WorkerService* WorkerService::GetInstance() { 28 WorkerService* WorkerService::GetInstance() {
32 return WorkerServiceImpl::GetInstance(); 29 return WorkerServiceImpl::GetInstance();
33 } 30 }
34 31
35 WorkerServiceImpl* WorkerServiceImpl::GetInstance() { 32 WorkerServiceImpl* WorkerServiceImpl::GetInstance() {
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 33 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
37 return Singleton<WorkerServiceImpl>::get(); 34 return Singleton<WorkerServiceImpl>::get();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 if (iter->worker_document_set()->IsEmpty()) { 203 if (iter->worker_document_set()->IsEmpty()) {
207 iter = pending_shared_workers_.erase(iter); 204 iter = pending_shared_workers_.erase(iter);
208 } else { 205 } else {
209 ++iter; 206 ++iter;
210 } 207 }
211 } 208 }
212 } 209 }
213 210
214 bool WorkerServiceImpl::CreateWorkerFromInstance( 211 bool WorkerServiceImpl::CreateWorkerFromInstance(
215 WorkerProcessHost::WorkerInstance instance) { 212 WorkerProcessHost::WorkerInstance instance) {
216 // TODO(michaeln): We need to ensure that a process is working 213 if (!CanCreateWorkerProcess(instance)) {
217 // on behalf of a single browser context. The process sharing logic below 214 queued_workers_.push_back(instance);
218 // does not ensure that. Consider making WorkerService a per browser context 215 return true;
219 // object to help with this.
220 WorkerProcessHost* worker = NULL;
221 if (CommandLine::ForCurrentProcess()->HasSwitch(
222 switches::kWebWorkerProcessPerCore)) {
223 worker = GetProcessToFillUpCores();
224 } else if (CommandLine::ForCurrentProcess()->HasSwitch(
225 switches::kWebWorkerShareProcesses)) {
226 worker = GetProcessForDomain(instance.url());
227 } else { // One process per worker.
228 if (!CanCreateWorkerProcess(instance)) {
229 queued_workers_.push_back(instance);
230 return true;
231 }
232 } 216 }
233 217
234 // Check to see if this shared worker is already running (two pages may have 218 // Check to see if this shared worker is already running (two pages may have
235 // tried to start up the worker simultaneously). 219 // tried to start up the worker simultaneously).
236 // See if a worker with this name already exists. 220 // See if a worker with this name already exists.
237 WorkerProcessHost::WorkerInstance* existing_instance = 221 WorkerProcessHost::WorkerInstance* existing_instance =
238 FindSharedWorkerInstance( 222 FindSharedWorkerInstance(
239 instance.url(), instance.name(), instance.partition(), 223 instance.url(), instance.name(), instance.partition(),
240 instance.resource_context()); 224 instance.resource_context());
241 WorkerProcessHost::WorkerInstance::FilterInfo filter_info = 225 WorkerProcessHost::WorkerInstance::FilterInfo filter_info =
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 DCHECK(iter->NumFilters() == 1); 272 DCHECK(iter->NumFilters() == 1);
289 WorkerProcessHost::WorkerInstance::FilterInfo filter_info = 273 WorkerProcessHost::WorkerInstance::FilterInfo filter_info =
290 iter->GetFilter(); 274 iter->GetFilter();
291 instance.AddFilter(filter_info.first, filter_info.second); 275 instance.AddFilter(filter_info.first, filter_info.second);
292 iter = queued_workers_.erase(iter); 276 iter = queued_workers_.erase(iter);
293 } else { 277 } else {
294 ++iter; 278 ++iter;
295 } 279 }
296 } 280 }
297 281
298 if (!worker) { 282 WorkerMessageFilter* first_filter = instance.filters().begin()->first;
299 WorkerMessageFilter* first_filter = instance.filters().begin()->first; 283 WorkerProcessHost* worker = new WorkerProcessHost(
300 worker = new WorkerProcessHost(instance.resource_context(), 284 instance.resource_context(), instance.partition());
301 instance.partition()); 285 // TODO(atwilson): This won't work if the message is from a worker process.
302 // TODO(atwilson): This won't work if the message is from a worker process. 286 // We don't support that yet though (this message is only sent from
303 // We don't support that yet though (this message is only sent from 287 // renderers) but when we do, we'll need to add code to pass in the current
304 // renderers) but when we do, we'll need to add code to pass in the current 288 // worker's document set for nested workers.
305 // worker's document set for nested workers. 289 if (!worker->Init(first_filter->render_process_id())) {
306 if (!worker->Init(first_filter->render_process_id())) { 290 delete worker;
307 delete worker; 291 return false;
308 return false;
309 }
310 } 292 }
311 293
312 // TODO(michaeln): As written, test can fail per my earlier comment in
313 // this method, but that's a bug.
314 // DCHECK(worker->request_context() == instance.GetRequestContext());
315
316 worker->CreateWorker(instance); 294 worker->CreateWorker(instance);
317 FOR_EACH_OBSERVER( 295 FOR_EACH_OBSERVER(
318 WorkerServiceObserver, observers_, 296 WorkerServiceObserver, observers_,
319 WorkerCreated(instance.url(), instance.name(), worker->GetData().id, 297 WorkerCreated(instance.url(), instance.name(), worker->GetData().id,
320 instance.worker_route_id())); 298 instance.worker_route_id()));
321 WorkerDevToolsManager::GetInstance()->WorkerCreated(worker, instance); 299 WorkerDevToolsManager::GetInstance()->WorkerCreated(worker, instance);
322 return true; 300 return true;
323 } 301 }
324 302
325 WorkerProcessHost* WorkerServiceImpl::GetProcessForDomain(const GURL& url) {
326 int num_processes = 0;
327 std::string domain =
328 net::RegistryControlledDomainService::GetDomainAndRegistry(url);
329 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
330 num_processes++;
331 for (WorkerProcessHost::Instances::const_iterator instance =
332 iter->instances().begin();
333 instance != iter->instances().end(); ++instance) {
334 if (net::RegistryControlledDomainService::GetDomainAndRegistry(
335 instance->url()) == domain) {
336 return *iter;
337 }
338 }
339 }
340
341 if (num_processes >= kMaxWorkerProcessesWhenSharing)
342 return GetLeastLoadedWorker();
343
344 return NULL;
345 }
346
347 WorkerProcessHost* WorkerServiceImpl::GetProcessToFillUpCores() {
348 int num_processes = 0;
349 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter)
350 num_processes++;
351
352 if (num_processes >= base::SysInfo::NumberOfProcessors())
353 return GetLeastLoadedWorker();
354
355 return NULL;
356 }
357
358 WorkerProcessHost* WorkerServiceImpl::GetLeastLoadedWorker() {
359 WorkerProcessHost* smallest = NULL;
360 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
361 if (!smallest || iter->instances().size() < smallest->instances().size())
362 smallest = *iter;
363 }
364
365 return smallest;
366 }
367
368 bool WorkerServiceImpl::CanCreateWorkerProcess( 303 bool WorkerServiceImpl::CanCreateWorkerProcess(
369 const WorkerProcessHost::WorkerInstance& instance) { 304 const WorkerProcessHost::WorkerInstance& instance) {
370 // Worker can be fired off if *any* parent has room. 305 // Worker can be fired off if *any* parent has room.
371 const WorkerDocumentSet::DocumentInfoSet& parents = 306 const WorkerDocumentSet::DocumentInfoSet& parents =
372 instance.worker_document_set()->documents(); 307 instance.worker_document_set()->documents();
373 308
374 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = 309 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter =
375 parents.begin(); 310 parents.begin();
376 parent_iter != parents.end(); ++parent_iter) { 311 parent_iter != parents.end(); ++parent_iter) {
377 bool hit_total_worker_limit = false; 312 bool hit_total_worker_limit = false;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 return instance; 520 return instance;
586 521
587 // No existing pending worker - create a new one. 522 // No existing pending worker - create a new one.
588 WorkerProcessHost::WorkerInstance pending( 523 WorkerProcessHost::WorkerInstance pending(
589 url, true, name, resource_context, partition); 524 url, true, name, resource_context, partition);
590 pending_shared_workers_.push_back(pending); 525 pending_shared_workers_.push_back(pending);
591 return &pending_shared_workers_.back(); 526 return &pending_shared_workers_.back();
592 } 527 }
593 528
594 } // namespace content 529 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/worker_host/worker_service_impl.h ('k') | content/public/common/content_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698