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_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" | 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/common/view_messages.h" | 16 #include "content/common/view_messages.h" |
17 #include "content/common/worker_messages.h" | 17 #include "content/common/worker_messages.h" |
| 18 #include "content/public/browser/child_process_data.h" |
18 #include "content/public/browser/worker_service_observer.h" | 19 #include "content/public/browser/worker_service_observer.h" |
19 #include "content/public/common/content_switches.h" | 20 #include "content/public/common/content_switches.h" |
20 #include "content/public/common/process_type.h" | 21 #include "content/public/common/process_type.h" |
21 #include "net/base/registry_controlled_domain.h" | 22 #include "net/base/registry_controlled_domain.h" |
22 | 23 |
23 namespace content { | 24 namespace content { |
24 | 25 |
25 const int WorkerServiceImpl::kMaxWorkerProcessesWhenSharing = 10; | 26 const int WorkerServiceImpl::kMaxWorkerProcessesWhenSharing = 10; |
26 const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64; | 27 const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64; |
27 const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16; | 28 const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16; |
(...skipping 10 matching lines...) Expand all Loading... |
38 WorkerServiceImpl::WorkerServiceImpl() : next_worker_route_id_(0) { | 39 WorkerServiceImpl::WorkerServiceImpl() : next_worker_route_id_(0) { |
39 } | 40 } |
40 | 41 |
41 WorkerServiceImpl::~WorkerServiceImpl() { | 42 WorkerServiceImpl::~WorkerServiceImpl() { |
42 // The observers in observers_ can't be used here because they might be | 43 // The observers in observers_ can't be used here because they might be |
43 // gone already. | 44 // gone already. |
44 } | 45 } |
45 | 46 |
46 void WorkerServiceImpl::OnWorkerMessageFilterClosing( | 47 void WorkerServiceImpl::OnWorkerMessageFilterClosing( |
47 WorkerMessageFilter* filter) { | 48 WorkerMessageFilter* filter) { |
48 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 49 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { |
49 !iter.Done(); ++iter) { | 50 iter->FilterShutdown(filter); |
50 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | |
51 worker->FilterShutdown(filter); | |
52 } | 51 } |
53 | 52 |
54 // See if that process had any queued workers. | 53 // See if that process had any queued workers. |
55 for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin(); | 54 for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin(); |
56 i != queued_workers_.end();) { | 55 i != queued_workers_.end();) { |
57 i->RemoveFilters(filter); | 56 i->RemoveFilters(filter); |
58 if (i->NumFilters() == 0) { | 57 if (i->NumFilters() == 0) { |
59 i = queued_workers_.erase(i); | 58 i = queued_workers_.erase(i); |
60 } else { | 59 } else { |
61 ++i; | 60 ++i; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 | 148 |
150 void WorkerServiceImpl::CancelCreateDedicatedWorker( | 149 void WorkerServiceImpl::CancelCreateDedicatedWorker( |
151 int route_id, | 150 int route_id, |
152 WorkerMessageFilter* filter) { | 151 WorkerMessageFilter* filter) { |
153 | 152 |
154 NOTREACHED(); | 153 NOTREACHED(); |
155 } | 154 } |
156 | 155 |
157 void WorkerServiceImpl::ForwardToWorker(const IPC::Message& message, | 156 void WorkerServiceImpl::ForwardToWorker(const IPC::Message& message, |
158 WorkerMessageFilter* filter) { | 157 WorkerMessageFilter* filter) { |
159 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 158 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { |
160 !iter.Done(); ++iter) { | 159 if (iter->FilterMessage(message, filter)) |
161 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | |
162 if (worker->FilterMessage(message, filter)) | |
163 return; | 160 return; |
164 } | 161 } |
165 | 162 |
166 // TODO(jabdelmalek): tell filter that callee is gone | 163 // TODO(jabdelmalek): tell filter that callee is gone |
167 } | 164 } |
168 | 165 |
169 void WorkerServiceImpl::DocumentDetached(unsigned long long document_id, | 166 void WorkerServiceImpl::DocumentDetached(unsigned long long document_id, |
170 WorkerMessageFilter* filter) { | 167 WorkerMessageFilter* filter) { |
171 // Any associated shared workers can be shut down. | 168 // Any associated shared workers can be shut down. |
172 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 169 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) |
173 !iter.Done(); ++iter) { | 170 iter->DocumentDetached(filter, document_id); |
174 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | |
175 worker->DocumentDetached(filter, document_id); | |
176 } | |
177 | 171 |
178 // Remove any queued shared workers for this document. | 172 // Remove any queued shared workers for this document. |
179 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); | 173 for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); |
180 iter != queued_workers_.end();) { | 174 iter != queued_workers_.end();) { |
181 | 175 |
182 iter->worker_document_set()->Remove(filter, document_id); | 176 iter->worker_document_set()->Remove(filter, document_id); |
183 if (iter->worker_document_set()->IsEmpty()) { | 177 if (iter->worker_document_set()->IsEmpty()) { |
184 iter = queued_workers_.erase(iter); | 178 iter = queued_workers_.erase(iter); |
185 continue; | 179 continue; |
186 } | 180 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 worker->CreateWorker(instance); | 296 worker->CreateWorker(instance); |
303 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, | 297 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, |
304 WorkerCreated(worker, instance)); | 298 WorkerCreated(worker, instance)); |
305 return true; | 299 return true; |
306 } | 300 } |
307 | 301 |
308 WorkerProcessHost* WorkerServiceImpl::GetProcessForDomain(const GURL& url) { | 302 WorkerProcessHost* WorkerServiceImpl::GetProcessForDomain(const GURL& url) { |
309 int num_processes = 0; | 303 int num_processes = 0; |
310 std::string domain = | 304 std::string domain = |
311 net::RegistryControlledDomainService::GetDomainAndRegistry(url); | 305 net::RegistryControlledDomainService::GetDomainAndRegistry(url); |
312 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 306 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { |
313 !iter.Done(); ++iter) { | |
314 num_processes++; | 307 num_processes++; |
315 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | |
316 for (WorkerProcessHost::Instances::const_iterator instance = | 308 for (WorkerProcessHost::Instances::const_iterator instance = |
317 worker->instances().begin(); | 309 iter->instances().begin(); |
318 instance != worker->instances().end(); ++instance) { | 310 instance != iter->instances().end(); ++instance) { |
319 if (net::RegistryControlledDomainService::GetDomainAndRegistry( | 311 if (net::RegistryControlledDomainService::GetDomainAndRegistry( |
320 instance->url()) == domain) { | 312 instance->url()) == domain) { |
321 return worker; | 313 return *iter; |
322 } | 314 } |
323 } | 315 } |
324 } | 316 } |
325 | 317 |
326 if (num_processes >= kMaxWorkerProcessesWhenSharing) | 318 if (num_processes >= kMaxWorkerProcessesWhenSharing) |
327 return GetLeastLoadedWorker(); | 319 return GetLeastLoadedWorker(); |
328 | 320 |
329 return NULL; | 321 return NULL; |
330 } | 322 } |
331 | 323 |
332 WorkerProcessHost* WorkerServiceImpl::GetProcessToFillUpCores() { | 324 WorkerProcessHost* WorkerServiceImpl::GetProcessToFillUpCores() { |
333 int num_processes = 0; | 325 int num_processes = 0; |
334 BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 326 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) |
335 for (; !iter.Done(); ++iter) | |
336 num_processes++; | 327 num_processes++; |
337 | 328 |
338 if (num_processes >= base::SysInfo::NumberOfProcessors()) | 329 if (num_processes >= base::SysInfo::NumberOfProcessors()) |
339 return GetLeastLoadedWorker(); | 330 return GetLeastLoadedWorker(); |
340 | 331 |
341 return NULL; | 332 return NULL; |
342 } | 333 } |
343 | 334 |
344 WorkerProcessHost* WorkerServiceImpl::GetLeastLoadedWorker() { | 335 WorkerProcessHost* WorkerServiceImpl::GetLeastLoadedWorker() { |
345 WorkerProcessHost* smallest = NULL; | 336 WorkerProcessHost* smallest = NULL; |
346 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 337 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { |
347 !iter.Done(); ++iter) { | 338 if (!smallest || iter->instances().size() < smallest->instances().size()) |
348 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 339 smallest = *iter; |
349 if (!smallest || worker->instances().size() < smallest->instances().size()) | |
350 smallest = worker; | |
351 } | 340 } |
352 | 341 |
353 return smallest; | 342 return smallest; |
354 } | 343 } |
355 | 344 |
356 bool WorkerServiceImpl::CanCreateWorkerProcess( | 345 bool WorkerServiceImpl::CanCreateWorkerProcess( |
357 const WorkerProcessHost::WorkerInstance& instance) { | 346 const WorkerProcessHost::WorkerInstance& instance) { |
358 // Worker can be fired off if *any* parent has room. | 347 // Worker can be fired off if *any* parent has room. |
359 const WorkerDocumentSet::DocumentInfoSet& parents = | 348 const WorkerDocumentSet::DocumentInfoSet& parents = |
360 instance.worker_document_set()->documents(); | 349 instance.worker_document_set()->documents(); |
(...skipping 17 matching lines...) Expand all Loading... |
378 return false; | 367 return false; |
379 } | 368 } |
380 | 369 |
381 bool WorkerServiceImpl::TabCanCreateWorkerProcess( | 370 bool WorkerServiceImpl::TabCanCreateWorkerProcess( |
382 int render_process_id, | 371 int render_process_id, |
383 int render_view_id, | 372 int render_view_id, |
384 bool* hit_total_worker_limit) { | 373 bool* hit_total_worker_limit) { |
385 int total_workers = 0; | 374 int total_workers = 0; |
386 int workers_per_tab = 0; | 375 int workers_per_tab = 0; |
387 *hit_total_worker_limit = false; | 376 *hit_total_worker_limit = false; |
388 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 377 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { |
389 !iter.Done(); ++iter) { | |
390 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | |
391 for (WorkerProcessHost::Instances::const_iterator cur_instance = | 378 for (WorkerProcessHost::Instances::const_iterator cur_instance = |
392 worker->instances().begin(); | 379 iter->instances().begin(); |
393 cur_instance != worker->instances().end(); ++cur_instance) { | 380 cur_instance != iter->instances().end(); ++cur_instance) { |
394 total_workers++; | 381 total_workers++; |
395 if (total_workers >= kMaxWorkersWhenSeparate) { | 382 if (total_workers >= kMaxWorkersWhenSeparate) { |
396 *hit_total_worker_limit = true; | 383 *hit_total_worker_limit = true; |
397 return false; | 384 return false; |
398 } | 385 } |
399 if (cur_instance->RendererIsParent(render_process_id, render_view_id)) { | 386 if (cur_instance->RendererIsParent(render_process_id, render_view_id)) { |
400 workers_per_tab++; | 387 workers_per_tab++; |
401 if (workers_per_tab >= kMaxWorkersPerTabWhenSeparate) | 388 if (workers_per_tab >= kMaxWorkersPerTabWhenSeparate) |
402 return false; | 389 return false; |
403 } | 390 } |
(...skipping 22 matching lines...) Expand all Loading... |
426 i = queued_workers_.begin(); | 413 i = queued_workers_.begin(); |
427 } else { | 414 } else { |
428 ++i; | 415 ++i; |
429 } | 416 } |
430 } | 417 } |
431 } | 418 } |
432 | 419 |
433 bool WorkerServiceImpl::GetRendererForWorker(int worker_process_id, | 420 bool WorkerServiceImpl::GetRendererForWorker(int worker_process_id, |
434 int* render_process_id, | 421 int* render_process_id, |
435 int* render_view_id) const { | 422 int* render_view_id) const { |
436 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 423 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { |
437 !iter.Done(); ++iter) { | 424 if (iter.GetData().id != worker_process_id) |
438 if (iter->data().id != worker_process_id) | |
439 continue; | 425 continue; |
440 | 426 |
441 // This code assumes one worker per process, see function comment in header! | 427 // This code assumes one worker per process, see function comment in header! |
442 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | |
443 WorkerProcessHost::Instances::const_iterator first_instance = | 428 WorkerProcessHost::Instances::const_iterator first_instance = |
444 worker->instances().begin(); | 429 iter->instances().begin(); |
445 if (first_instance == worker->instances().end()) | 430 if (first_instance == iter->instances().end()) |
446 return false; | 431 return false; |
447 | 432 |
448 WorkerDocumentSet::DocumentInfoSet::const_iterator info = | 433 WorkerDocumentSet::DocumentInfoSet::const_iterator info = |
449 first_instance->worker_document_set()->documents().begin(); | 434 first_instance->worker_document_set()->documents().begin(); |
450 *render_process_id = info->render_process_id(); | 435 *render_process_id = info->render_process_id(); |
451 *render_view_id = info->render_view_id(); | 436 *render_view_id = info->render_view_id(); |
452 return true; | 437 return true; |
453 } | 438 } |
454 return false; | 439 return false; |
455 } | 440 } |
456 | 441 |
457 const WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindWorkerInstance( | 442 const WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindWorkerInstance( |
458 int worker_process_id) { | 443 int worker_process_id) { |
459 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 444 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { |
460 !iter.Done(); ++iter) { | 445 if (iter.GetData().id != worker_process_id) |
461 if (iter->data().id != worker_process_id) | |
462 continue; | 446 continue; |
463 | 447 |
464 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | |
465 WorkerProcessHost::Instances::const_iterator instance = | 448 WorkerProcessHost::Instances::const_iterator instance = |
466 worker->instances().begin(); | 449 iter->instances().begin(); |
467 return instance == worker->instances().end() ? NULL : &*instance; | 450 return instance == iter->instances().end() ? NULL : &*instance; |
468 } | 451 } |
469 return NULL; | 452 return NULL; |
470 } | 453 } |
471 | 454 |
472 void WorkerServiceImpl::AddObserver(WorkerServiceObserver* observer) { | 455 void WorkerServiceImpl::AddObserver(WorkerServiceObserver* observer) { |
473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
474 observers_.AddObserver(observer); | 457 observers_.AddObserver(observer); |
475 } | 458 } |
476 | 459 |
477 void WorkerServiceImpl::RemoveObserver(WorkerServiceObserver* observer) { | 460 void WorkerServiceImpl::RemoveObserver(WorkerServiceObserver* observer) { |
(...skipping 11 matching lines...) Expand all Loading... |
489 void WorkerServiceImpl::NotifyWorkerContextStarted(WorkerProcessHost* process, | 472 void WorkerServiceImpl::NotifyWorkerContextStarted(WorkerProcessHost* process, |
490 int worker_route_id) { | 473 int worker_route_id) { |
491 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, | 474 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, |
492 WorkerContextStarted(process, worker_route_id)); | 475 WorkerContextStarted(process, worker_route_id)); |
493 } | 476 } |
494 | 477 |
495 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance( | 478 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance( |
496 const GURL& url, | 479 const GURL& url, |
497 const string16& name, | 480 const string16& name, |
498 const content::ResourceContext* resource_context) { | 481 const content::ResourceContext* resource_context) { |
499 for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); | 482 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { |
500 !iter.Done(); ++iter) { | |
501 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | |
502 for (WorkerProcessHost::Instances::iterator instance_iter = | 483 for (WorkerProcessHost::Instances::iterator instance_iter = |
503 worker->mutable_instances().begin(); | 484 iter->mutable_instances().begin(); |
504 instance_iter != worker->mutable_instances().end(); | 485 instance_iter != iter->mutable_instances().end(); |
505 ++instance_iter) { | 486 ++instance_iter) { |
506 if (instance_iter->Matches(url, name, resource_context)) | 487 if (instance_iter->Matches(url, name, resource_context)) |
507 return &(*instance_iter); | 488 return &(*instance_iter); |
508 } | 489 } |
509 } | 490 } |
510 return NULL; | 491 return NULL; |
511 } | 492 } |
512 | 493 |
513 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindPendingInstance( | 494 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindPendingInstance( |
514 const GURL& url, | 495 const GURL& url, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 if (instance) | 534 if (instance) |
554 return instance; | 535 return instance; |
555 | 536 |
556 // No existing pending worker - create a new one. | 537 // No existing pending worker - create a new one. |
557 WorkerProcessHost::WorkerInstance pending(url, true, name, resource_context); | 538 WorkerProcessHost::WorkerInstance pending(url, true, name, resource_context); |
558 pending_shared_workers_.push_back(pending); | 539 pending_shared_workers_.push_back(pending); |
559 return &pending_shared_workers_.back(); | 540 return &pending_shared_workers_.back(); |
560 } | 541 } |
561 | 542 |
562 } // namespace content | 543 } // namespace content |
OLD | NEW |