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

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

Issue 9150017: Add a Content API around BrowserChildProcessHost, similar to what was done with ChildProcessHost.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix?! Created 8 years, 11 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
« no previous file with comments | « content/browser/worker_host/worker_process_host.cc ('k') | content/content_browser.gypi » ('j') | 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) 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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/worker_host/worker_process_host.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698