OLD | NEW |
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" |
11 #include "base/sys_info.h" | 11 #include "base/sys_info.h" |
12 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
13 #include "content/browser/resource_context.h" | 13 #include "content/browser/resource_context.h" |
14 #include "content/browser/worker_host/worker_message_filter.h" | 14 #include "content/browser/worker_host/worker_message_filter.h" |
15 #include "content/browser/worker_host/worker_process_host.h" | 15 #include "content/browser/worker_host/worker_process_host.h" |
16 #include "content/browser/worker_host/worker_service_observer.h" | 16 #include "content/browser/worker_host/worker_service_observer.h" |
17 #include "content/common/view_messages.h" | 17 #include "content/common/view_messages.h" |
18 #include "content/common/worker_messages.h" | 18 #include "content/common/worker_messages.h" |
19 #include "content/public/common/content_switches.h" | 19 #include "content/public/common/content_switches.h" |
| 20 #include "content/public/common/process_type.h" |
20 #include "net/base/registry_controlled_domain.h" | 21 #include "net/base/registry_controlled_domain.h" |
21 | 22 |
22 using content::BrowserThread; | 23 using content::BrowserThread; |
23 | 24 |
24 const int WorkerService::kMaxWorkerProcessesWhenSharing = 10; | 25 const int WorkerService::kMaxWorkerProcessesWhenSharing = 10; |
25 const int WorkerService::kMaxWorkersWhenSeparate = 64; | 26 const int WorkerService::kMaxWorkersWhenSeparate = 64; |
26 const int WorkerService::kMaxWorkersPerTabWhenSeparate = 16; | 27 const int WorkerService::kMaxWorkersPerTabWhenSeparate = 16; |
27 | 28 |
28 WorkerService* WorkerService::GetInstance() { | 29 WorkerService* WorkerService::GetInstance() { |
29 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 30 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
30 return Singleton<WorkerService>::get(); | 31 return Singleton<WorkerService>::get(); |
31 } | 32 } |
32 | 33 |
33 WorkerService::WorkerService() : next_worker_route_id_(0) { | 34 WorkerService::WorkerService() : next_worker_route_id_(0) { |
34 } | 35 } |
35 | 36 |
36 WorkerService::~WorkerService() { | 37 WorkerService::~WorkerService() { |
37 // The observers in observers_ can't be used here because they might be | 38 // The observers in observers_ can't be used here because they might be |
38 // gone already. | 39 // gone already. |
39 } | 40 } |
40 | 41 |
41 void WorkerService::OnWorkerMessageFilterClosing(WorkerMessageFilter* filter) { | 42 void WorkerService::OnWorkerMessageFilterClosing(WorkerMessageFilter* filter) { |
42 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 43 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
43 !iter.Done(); ++iter) { | 44 !iter.Done(); ++iter) { |
44 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 45 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
45 worker->FilterShutdown(filter); | 46 worker->FilterShutdown(filter); |
46 } | 47 } |
47 | 48 |
48 // See if that process had any queued workers. | 49 // See if that process had any queued workers. |
49 for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin(); | 50 for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin(); |
50 i != queued_workers_.end();) { | 51 i != queued_workers_.end();) { |
51 i->RemoveFilters(filter); | 52 i->RemoveFilters(filter); |
52 if (i->NumFilters() == 0) { | 53 if (i->NumFilters() == 0) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 | 144 |
144 void WorkerService::CancelCreateDedicatedWorker( | 145 void WorkerService::CancelCreateDedicatedWorker( |
145 int route_id, | 146 int route_id, |
146 WorkerMessageFilter* filter) { | 147 WorkerMessageFilter* filter) { |
147 | 148 |
148 NOTREACHED(); | 149 NOTREACHED(); |
149 } | 150 } |
150 | 151 |
151 void WorkerService::ForwardToWorker(const IPC::Message& message, | 152 void WorkerService::ForwardToWorker(const IPC::Message& message, |
152 WorkerMessageFilter* filter) { | 153 WorkerMessageFilter* filter) { |
153 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 154 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
154 !iter.Done(); ++iter) { | 155 !iter.Done(); ++iter) { |
155 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 156 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
156 if (worker->FilterMessage(message, filter)) | 157 if (worker->FilterMessage(message, filter)) |
157 return; | 158 return; |
158 } | 159 } |
159 | 160 |
160 // TODO(jabdelmalek): tell filter that callee is gone | 161 // TODO(jabdelmalek): tell filter that callee is gone |
161 } | 162 } |
162 | 163 |
163 void WorkerService::DocumentDetached(unsigned long long document_id, | 164 void WorkerService::DocumentDetached(unsigned long long document_id, |
164 WorkerMessageFilter* filter) { | 165 WorkerMessageFilter* filter) { |
165 // Any associated shared workers can be shut down. | 166 // Any associated shared workers can be shut down. |
166 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 167 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
167 !iter.Done(); ++iter) { | 168 !iter.Done(); ++iter) { |
168 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 169 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
169 worker->DocumentDetached(filter, document_id); | 170 worker->DocumentDetached(filter, document_id); |
170 } | 171 } |
171 | 172 |
172 // Remove any queued shared workers for this document. | 173 // Remove any queued shared workers for this document. |
173 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); | 174 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); |
174 iter != queued_workers_.end();) { | 175 iter != queued_workers_.end();) { |
175 | 176 |
176 iter->worker_document_set()->Remove(filter, document_id); | 177 iter->worker_document_set()->Remove(filter, document_id); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 worker->CreateWorker(instance); | 299 worker->CreateWorker(instance); |
299 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, | 300 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, |
300 WorkerCreated(worker, instance)); | 301 WorkerCreated(worker, instance)); |
301 return true; | 302 return true; |
302 } | 303 } |
303 | 304 |
304 WorkerProcessHost* WorkerService::GetProcessForDomain(const GURL& url) { | 305 WorkerProcessHost* WorkerService::GetProcessForDomain(const GURL& url) { |
305 int num_processes = 0; | 306 int num_processes = 0; |
306 std::string domain = | 307 std::string domain = |
307 net::RegistryControlledDomainService::GetDomainAndRegistry(url); | 308 net::RegistryControlledDomainService::GetDomainAndRegistry(url); |
308 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 309 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
309 !iter.Done(); ++iter) { | 310 !iter.Done(); ++iter) { |
310 num_processes++; | 311 num_processes++; |
311 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 312 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
312 for (WorkerProcessHost::Instances::const_iterator instance = | 313 for (WorkerProcessHost::Instances::const_iterator instance = |
313 worker->instances().begin(); | 314 worker->instances().begin(); |
314 instance != worker->instances().end(); ++instance) { | 315 instance != worker->instances().end(); ++instance) { |
315 if (net::RegistryControlledDomainService::GetDomainAndRegistry( | 316 if (net::RegistryControlledDomainService::GetDomainAndRegistry( |
316 instance->url()) == domain) { | 317 instance->url()) == domain) { |
317 return worker; | 318 return worker; |
318 } | 319 } |
319 } | 320 } |
320 } | 321 } |
321 | 322 |
322 if (num_processes >= kMaxWorkerProcessesWhenSharing) | 323 if (num_processes >= kMaxWorkerProcessesWhenSharing) |
323 return GetLeastLoadedWorker(); | 324 return GetLeastLoadedWorker(); |
324 | 325 |
325 return NULL; | 326 return NULL; |
326 } | 327 } |
327 | 328 |
328 WorkerProcessHost* WorkerService::GetProcessToFillUpCores() { | 329 WorkerProcessHost* WorkerService::GetProcessToFillUpCores() { |
329 int num_processes = 0; | 330 int num_processes = 0; |
330 BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 331 BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
331 for (; !iter.Done(); ++iter) | 332 for (; !iter.Done(); ++iter) |
332 num_processes++; | 333 num_processes++; |
333 | 334 |
334 if (num_processes >= base::SysInfo::NumberOfProcessors()) | 335 if (num_processes >= base::SysInfo::NumberOfProcessors()) |
335 return GetLeastLoadedWorker(); | 336 return GetLeastLoadedWorker(); |
336 | 337 |
337 return NULL; | 338 return NULL; |
338 } | 339 } |
339 | 340 |
340 WorkerProcessHost* WorkerService::GetLeastLoadedWorker() { | 341 WorkerProcessHost* WorkerService::GetLeastLoadedWorker() { |
341 WorkerProcessHost* smallest = NULL; | 342 WorkerProcessHost* smallest = NULL; |
342 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 343 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
343 !iter.Done(); ++iter) { | 344 !iter.Done(); ++iter) { |
344 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 345 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
345 if (!smallest || worker->instances().size() < smallest->instances().size()) | 346 if (!smallest || worker->instances().size() < smallest->instances().size()) |
346 smallest = worker; | 347 smallest = worker; |
347 } | 348 } |
348 | 349 |
349 return smallest; | 350 return smallest; |
350 } | 351 } |
351 | 352 |
352 bool WorkerService::CanCreateWorkerProcess( | 353 bool WorkerService::CanCreateWorkerProcess( |
(...skipping 20 matching lines...) Expand all Loading... |
373 // instance. | 374 // instance. |
374 return false; | 375 return false; |
375 } | 376 } |
376 | 377 |
377 bool WorkerService::TabCanCreateWorkerProcess(int render_process_id, | 378 bool WorkerService::TabCanCreateWorkerProcess(int render_process_id, |
378 int render_view_id, | 379 int render_view_id, |
379 bool* hit_total_worker_limit) { | 380 bool* hit_total_worker_limit) { |
380 int total_workers = 0; | 381 int total_workers = 0; |
381 int workers_per_tab = 0; | 382 int workers_per_tab = 0; |
382 *hit_total_worker_limit = false; | 383 *hit_total_worker_limit = false; |
383 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 384 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
384 !iter.Done(); ++iter) { | 385 !iter.Done(); ++iter) { |
385 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 386 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
386 for (WorkerProcessHost::Instances::const_iterator cur_instance = | 387 for (WorkerProcessHost::Instances::const_iterator cur_instance = |
387 worker->instances().begin(); | 388 worker->instances().begin(); |
388 cur_instance != worker->instances().end(); ++cur_instance) { | 389 cur_instance != worker->instances().end(); ++cur_instance) { |
389 total_workers++; | 390 total_workers++; |
390 if (total_workers >= kMaxWorkersWhenSeparate) { | 391 if (total_workers >= kMaxWorkersWhenSeparate) { |
391 *hit_total_worker_limit = true; | 392 *hit_total_worker_limit = true; |
392 return false; | 393 return false; |
393 } | 394 } |
(...skipping 27 matching lines...) Expand all Loading... |
421 i = queued_workers_.begin(); | 422 i = queued_workers_.begin(); |
422 } else { | 423 } else { |
423 ++i; | 424 ++i; |
424 } | 425 } |
425 } | 426 } |
426 } | 427 } |
427 | 428 |
428 bool WorkerService::GetRendererForWorker(int worker_process_id, | 429 bool WorkerService::GetRendererForWorker(int worker_process_id, |
429 int* render_process_id, | 430 int* render_process_id, |
430 int* render_view_id) const { | 431 int* render_view_id) const { |
431 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 432 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
432 !iter.Done(); ++iter) { | 433 !iter.Done(); ++iter) { |
433 if (iter->id() != worker_process_id) | 434 if (iter->id() != worker_process_id) |
434 continue; | 435 continue; |
435 | 436 |
436 // This code assumes one worker per process, see function comment in header! | 437 // This code assumes one worker per process, see function comment in header! |
437 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 438 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
438 WorkerProcessHost::Instances::const_iterator first_instance = | 439 WorkerProcessHost::Instances::const_iterator first_instance = |
439 worker->instances().begin(); | 440 worker->instances().begin(); |
440 if (first_instance == worker->instances().end()) | 441 if (first_instance == worker->instances().end()) |
441 return false; | 442 return false; |
442 | 443 |
443 WorkerDocumentSet::DocumentInfoSet::const_iterator info = | 444 WorkerDocumentSet::DocumentInfoSet::const_iterator info = |
444 first_instance->worker_document_set()->documents().begin(); | 445 first_instance->worker_document_set()->documents().begin(); |
445 *render_process_id = info->render_process_id(); | 446 *render_process_id = info->render_process_id(); |
446 *render_view_id = info->render_view_id(); | 447 *render_view_id = info->render_view_id(); |
447 return true; | 448 return true; |
448 } | 449 } |
449 return false; | 450 return false; |
450 } | 451 } |
451 | 452 |
452 const WorkerProcessHost::WorkerInstance* WorkerService::FindWorkerInstance( | 453 const WorkerProcessHost::WorkerInstance* WorkerService::FindWorkerInstance( |
453 int worker_process_id) { | 454 int worker_process_id) { |
454 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 455 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
455 !iter.Done(); ++iter) { | 456 !iter.Done(); ++iter) { |
456 if (iter->id() != worker_process_id) | 457 if (iter->id() != worker_process_id) |
457 continue; | 458 continue; |
458 | 459 |
459 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 460 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
460 WorkerProcessHost::Instances::const_iterator instance = | 461 WorkerProcessHost::Instances::const_iterator instance = |
461 worker->instances().begin(); | 462 worker->instances().begin(); |
462 return instance == worker->instances().end() ? NULL : &*instance; | 463 return instance == worker->instances().end() ? NULL : &*instance; |
463 } | 464 } |
464 return NULL; | 465 return NULL; |
(...skipping 20 matching lines...) Expand all Loading... |
485 int worker_route_id) { | 486 int worker_route_id) { |
486 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, | 487 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, |
487 WorkerContextStarted(process, worker_route_id)); | 488 WorkerContextStarted(process, worker_route_id)); |
488 } | 489 } |
489 | 490 |
490 WorkerProcessHost::WorkerInstance* | 491 WorkerProcessHost::WorkerInstance* |
491 WorkerService::FindSharedWorkerInstance( | 492 WorkerService::FindSharedWorkerInstance( |
492 const GURL& url, | 493 const GURL& url, |
493 const string16& name, | 494 const string16& name, |
494 const content::ResourceContext* resource_context) { | 495 const content::ResourceContext* resource_context) { |
495 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 496 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); |
496 !iter.Done(); ++iter) { | 497 !iter.Done(); ++iter) { |
497 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 498 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); |
498 for (WorkerProcessHost::Instances::iterator instance_iter = | 499 for (WorkerProcessHost::Instances::iterator instance_iter = |
499 worker->mutable_instances().begin(); | 500 worker->mutable_instances().begin(); |
500 instance_iter != worker->mutable_instances().end(); | 501 instance_iter != worker->mutable_instances().end(); |
501 ++instance_iter) { | 502 ++instance_iter) { |
502 if (instance_iter->Matches(url, name, resource_context)) | 503 if (instance_iter->Matches(url, name, resource_context)) |
503 return &(*instance_iter); | 504 return &(*instance_iter); |
504 } | 505 } |
505 } | 506 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 WorkerProcessHost::WorkerInstance* instance = | 550 WorkerProcessHost::WorkerInstance* instance = |
550 FindPendingInstance(url, name, resource_context); | 551 FindPendingInstance(url, name, resource_context); |
551 if (instance) | 552 if (instance) |
552 return instance; | 553 return instance; |
553 | 554 |
554 // No existing pending worker - create a new one. | 555 // No existing pending worker - create a new one. |
555 WorkerProcessHost::WorkerInstance pending(url, true, name, resource_context); | 556 WorkerProcessHost::WorkerInstance pending(url, true, name, resource_context); |
556 pending_shared_workers_.push_back(pending); | 557 pending_shared_workers_.push_back(pending); |
557 return &pending_shared_workers_.back(); | 558 return &pending_shared_workers_.back(); |
558 } | 559 } |
OLD | NEW |