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

Side by Side Diff: chrome/browser/worker_host/worker_process_host.cc

Issue 509016: Refactored code to allow associating workers with multiple renderers. (Closed)
Patch Set: Disabled overly-aggressive assertion in ResourceDispatcherHost. Created 10 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "chrome/browser/worker_host/worker_process_host.h" 5 #include "chrome/browser/worker_host/worker_process_host.h"
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 WorkerService::GetInstance(), &WorkerService::next_worker_route_id)); 58 WorkerService::GetInstance(), &WorkerService::next_worker_route_id));
59 } 59 }
60 60
61 WorkerProcessHost::~WorkerProcessHost() { 61 WorkerProcessHost::~WorkerProcessHost() {
62 // Let interested observers know we are being deleted. 62 // Let interested observers know we are being deleted.
63 NotificationService::current()->Notify( 63 NotificationService::current()->Notify(
64 NotificationType::WORKER_PROCESS_HOST_SHUTDOWN, 64 NotificationType::WORKER_PROCESS_HOST_SHUTDOWN,
65 Source<WorkerProcessHost>(this), 65 Source<WorkerProcessHost>(this),
66 NotificationService::NoDetails()); 66 NotificationService::NoDetails());
67 67
68 // If we crashed, tell the RenderViewHost. 68 // If we crashed, tell the RenderViewHosts.
69 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { 69 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) {
70 ChromeThread::PostTask( 70 const WorkerDocumentSet::DocumentInfoSet& parents =
71 ChromeThread::UI, FROM_HERE, 71 i->worker_document_set()->documents();
72 new WorkerCrashTask(i->renderer_id(), i->render_view_route_id())); 72 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter =
73 parents.begin(); parent_iter != parents.end(); ++parent_iter) {
74 ChromeThread::PostTask(
75 ChromeThread::UI, FROM_HERE,
76 new WorkerCrashTask(parent_iter->renderer_id(),
77 parent_iter->render_view_route_id()));
78 }
73 } 79 }
74 80
75 ChildProcessSecurityPolicy::GetInstance()->Remove(id()); 81 ChildProcessSecurityPolicy::GetInstance()->Remove(id());
76 } 82 }
77 83
78 bool WorkerProcessHost::Init() { 84 bool WorkerProcessHost::Init() {
79 if (!CreateChannel()) 85 if (!CreateChannel())
80 return false; 86 return false;
81 87
82 FilePath exe_path = GetChildPath(); 88 FilePath exe_path = GetChildPath();
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 sender->Send(new_message); 329 sender->Send(new_message);
324 return; 330 return;
325 } 331 }
326 } 332 }
327 333
328 void WorkerProcessHost::SenderShutdown(IPC::Message::Sender* sender) { 334 void WorkerProcessHost::SenderShutdown(IPC::Message::Sender* sender) {
329 for (Instances::iterator i = instances_.begin(); i != instances_.end();) { 335 for (Instances::iterator i = instances_.begin(); i != instances_.end();) {
330 bool shutdown = false; 336 bool shutdown = false;
331 i->RemoveSenders(sender); 337 i->RemoveSenders(sender);
332 if (i->shared()) { 338 if (i->shared()) {
333 i->RemoveAllAssociatedDocuments(sender); 339 i->worker_document_set()->RemoveAll(sender);
334 if (i->IsDocumentSetEmpty()) { 340 if (i->worker_document_set()->IsEmpty()) {
335 shutdown = true; 341 shutdown = true;
336 } 342 }
337 } else if (i->NumSenders() == 0) { 343 } else if (i->NumSenders() == 0) {
338 shutdown = true; 344 shutdown = true;
339 } 345 }
340 if (shutdown) { 346 if (shutdown) {
341 Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id())); 347 Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id()));
342 i = instances_.erase(i); 348 i = instances_.erase(i);
343 } else { 349 } else {
344 ++i; 350 ++i;
(...skipping 22 matching lines...) Expand all
367 display_title += ", "; 373 display_title += ", ";
368 display_title += *i; 374 display_title += *i;
369 } 375 }
370 376
371 set_name(ASCIIToWide(display_title)); 377 set_name(ASCIIToWide(display_title));
372 } 378 }
373 379
374 void WorkerProcessHost::OnLookupSharedWorker(const GURL& url, 380 void WorkerProcessHost::OnLookupSharedWorker(const GURL& url,
375 const string16& name, 381 const string16& name,
376 unsigned long long document_id, 382 unsigned long long document_id,
383 int render_view_route_id,
377 int* route_id, 384 int* route_id,
378 bool* url_mismatch) { 385 bool* url_mismatch) {
379 int new_route_id = WorkerService::GetInstance()->next_worker_route_id(); 386 int new_route_id = WorkerService::GetInstance()->next_worker_route_id();
380 // TODO(atwilson): Add code to merge document sets for nested shared workers. 387 // TODO(atwilson): Add code to pass in the current worker's document set for
388 // these nested workers. Code below will not work for SharedWorkers as it
389 // only looks at a single parent.
390 DCHECK(instances_.front().worker_document_set()->documents().size() == 1);
391 WorkerDocumentSet::DocumentInfoSet::const_iterator first_parent =
392 instances_.front().worker_document_set()->documents().begin();
381 bool worker_found = WorkerService::GetInstance()->LookupSharedWorker( 393 bool worker_found = WorkerService::GetInstance()->LookupSharedWorker(
382 url, name, instances_.front().off_the_record(), document_id, this, 394 url, name, instances_.front().off_the_record(), document_id,
395 first_parent->renderer_id(), first_parent->render_view_route_id(), this,
383 new_route_id, url_mismatch); 396 new_route_id, url_mismatch);
384 *route_id = worker_found ? new_route_id : MSG_ROUTING_NONE; 397 *route_id = worker_found ? new_route_id : MSG_ROUTING_NONE;
385 } 398 }
386 399
387 void WorkerProcessHost::OnCreateWorker(const GURL& url, 400 void WorkerProcessHost::OnCreateWorker(
388 bool shared, 401 const ViewHostMsg_CreateWorker_Params& params, int* route_id) {
389 const string16& name,
390 int render_view_route_id,
391 int* route_id) {
392 DCHECK(instances_.size() == 1); // Only called when one process per worker. 402 DCHECK(instances_.size() == 1); // Only called when one process per worker.
403 // TODO(atwilson): Add code to pass in the current worker's document set for
404 // these nested workers. Code below will not work for SharedWorkers as it
405 // only looks at a single parent.
406 DCHECK(instances_.front().worker_document_set()->documents().size() == 1);
407 WorkerDocumentSet::DocumentInfoSet::const_iterator first_parent =
408 instances_.front().worker_document_set()->documents().begin();
393 *route_id = WorkerService::GetInstance()->next_worker_route_id(); 409 *route_id = WorkerService::GetInstance()->next_worker_route_id();
394 WorkerService::GetInstance()->CreateWorker( 410 WorkerService::GetInstance()->CreateWorker(
395 url, shared, instances_.front().off_the_record(), name, 411 params.url, params.is_shared, instances_.front().off_the_record(),
396 instances_.front().renderer_id(), 412 params.name, params.document_id, first_parent->renderer_id(),
397 instances_.front().render_view_route_id(), this, *route_id); 413 first_parent->render_view_route_id(), this, *route_id);
398 // TODO(atwilson): Add code to merge document sets for nested shared workers.
399 } 414 }
400 415
401 void WorkerProcessHost::OnCancelCreateDedicatedWorker(int route_id) { 416 void WorkerProcessHost::OnCancelCreateDedicatedWorker(int route_id) {
402 WorkerService::GetInstance()->CancelCreateDedicatedWorker(this, route_id); 417 WorkerService::GetInstance()->CancelCreateDedicatedWorker(this, route_id);
403 } 418 }
404 419
405 void WorkerProcessHost::OnForwardToWorker(const IPC::Message& message) { 420 void WorkerProcessHost::OnForwardToWorker(const IPC::Message& message) {
406 WorkerService::GetInstance()->ForwardMessage(message, this); 421 WorkerService::GetInstance()->ForwardMessage(message, this);
407 } 422 }
408 423
409 void WorkerProcessHost::DocumentDetached(IPC::Message::Sender* parent, 424 void WorkerProcessHost::DocumentDetached(IPC::Message::Sender* parent,
410 unsigned long long document_id) 425 unsigned long long document_id)
411 { 426 {
412 // Walk all instances and remove the document from their document set. 427 // Walk all instances and remove the document from their document set.
413 for (Instances::iterator i = instances_.begin(); i != instances_.end();) { 428 for (Instances::iterator i = instances_.begin(); i != instances_.end();) {
414 if (!i->shared()) { 429 if (!i->shared()) {
415 ++i; 430 ++i;
416 } else { 431 } else {
417 i->RemoveFromDocumentSet(parent, document_id); 432 i->worker_document_set()->Remove(parent, document_id);
418 if (i->IsDocumentSetEmpty()) { 433 if (i->worker_document_set()->IsEmpty()) {
419 // This worker has no more associated documents - shut it down. 434 // This worker has no more associated documents - shut it down.
420 Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id())); 435 Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id()));
421 i = instances_.erase(i); 436 i = instances_.erase(i);
422 } else { 437 } else {
423 ++i; 438 ++i;
424 } 439 }
425 } 440 }
426 } 441 }
427 } 442 }
428 443
429 WorkerProcessHost::WorkerInstance::WorkerInstance(const GURL& url, 444 WorkerProcessHost::WorkerInstance::WorkerInstance(const GURL& url,
430 bool shared, 445 bool shared,
431 bool off_the_record, 446 bool off_the_record,
432 const string16& name, 447 const string16& name,
433 int renderer_id,
434 int render_view_route_id,
435 int worker_route_id) 448 int worker_route_id)
436 : url_(url), 449 : url_(url),
437 shared_(shared), 450 shared_(shared),
438 off_the_record_(off_the_record), 451 off_the_record_(off_the_record),
439 closed_(false), 452 closed_(false),
440 name_(name), 453 name_(name),
441 renderer_id_(renderer_id), 454 worker_route_id_(worker_route_id),
442 render_view_route_id_(render_view_route_id), 455 worker_document_set_(new WorkerDocumentSet()) {
443 worker_route_id_(worker_route_id) {
444 } 456 }
445 457
446 // Compares an instance based on the algorithm in the WebWorkers spec - an 458 // Compares an instance based on the algorithm in the WebWorkers spec - an
447 // instance matches if the origins of the URLs match, and: 459 // instance matches if the origins of the URLs match, and:
448 // a) the names are non-empty and equal 460 // a) the names are non-empty and equal
449 // -or- 461 // -or-
450 // b) the names are both empty, and the urls are equal 462 // b) the names are both empty, and the urls are equal
451 bool WorkerProcessHost::WorkerInstance::Matches( 463 bool WorkerProcessHost::WorkerInstance::Matches(
452 const GURL& match_url, const string16& match_name, 464 const GURL& match_url, const string16& match_name,
453 bool off_the_record) const { 465 bool off_the_record) const {
454 // Only match open shared workers. 466 // Only match open shared workers.
455 if (!shared_ || closed_) 467 if (!shared_ || closed_)
456 return false; 468 return false;
457 469
458 // Incognito workers don't match non-incognito workers. 470 // Incognito workers don't match non-incognito workers.
459 if (off_the_record_ != off_the_record) 471 if (off_the_record_ != off_the_record)
460 return false; 472 return false;
461 473
462 if (url_.GetOrigin() != match_url.GetOrigin()) 474 if (url_.GetOrigin() != match_url.GetOrigin())
463 return false; 475 return false;
464 476
465 if (name_.empty() && match_name.empty()) 477 if (name_.empty() && match_name.empty())
466 return url_ == match_url; 478 return url_ == match_url;
467 479
468 return name_ == match_name; 480 return name_ == match_name;
469 } 481 }
470 482
471 void WorkerProcessHost::WorkerInstance::AddToDocumentSet(
472 IPC::Message::Sender* parent, unsigned long long document_id) {
473 if (!IsInDocumentSet(parent, document_id)) {
474 DocumentInfo info(parent, document_id);
475 document_set_.push_back(info);
476 }
477 }
478
479 bool WorkerProcessHost::WorkerInstance::IsInDocumentSet(
480 IPC::Message::Sender* parent, unsigned long long document_id) const {
481 for (DocumentSet::const_iterator i = document_set_.begin();
482 i != document_set_.end(); ++i) {
483 if (i->first == parent && i->second == document_id)
484 return true;
485 }
486 return false;
487 }
488
489 void WorkerProcessHost::WorkerInstance::RemoveFromDocumentSet(
490 IPC::Message::Sender* parent, unsigned long long document_id) {
491 for (DocumentSet::iterator i = document_set_.begin();
492 i != document_set_.end(); i++) {
493 if (i->first == parent && i->second == document_id) {
494 document_set_.erase(i);
495 break;
496 }
497 }
498 // Should not be duplicate copies in the document set.
499 DCHECK(!IsInDocumentSet(parent, document_id));
500 }
501
502 void WorkerProcessHost::WorkerInstance::RemoveAllAssociatedDocuments(
503 IPC::Message::Sender* parent) {
504 for (DocumentSet::iterator i = document_set_.begin();
505 i != document_set_.end();) {
506 if (i->first == parent)
507 i = document_set_.erase(i);
508 else
509 ++i;
510 }
511 }
512
513 void WorkerProcessHost::WorkerInstance::AddSender(IPC::Message::Sender* sender, 483 void WorkerProcessHost::WorkerInstance::AddSender(IPC::Message::Sender* sender,
514 int sender_route_id) { 484 int sender_route_id) {
515 if (!HasSender(sender, sender_route_id)) { 485 if (!HasSender(sender, sender_route_id)) {
516 SenderInfo info(sender, sender_route_id); 486 SenderInfo info(sender, sender_route_id);
517 senders_.push_back(info); 487 senders_.push_back(info);
518 } 488 }
519 // Only shared workers can have more than one associated sender. 489 // Only shared workers can have more than one associated sender.
520 DCHECK(shared_ || senders_.size() == 1); 490 DCHECK(shared_ || senders_.size() == 1);
521 } 491 }
522 492
(...skipping 22 matching lines...) Expand all
545 bool WorkerProcessHost::WorkerInstance::HasSender( 515 bool WorkerProcessHost::WorkerInstance::HasSender(
546 IPC::Message::Sender* sender, int sender_route_id) const { 516 IPC::Message::Sender* sender, int sender_route_id) const {
547 for (SenderList::const_iterator i = senders_.begin(); i != senders_.end(); 517 for (SenderList::const_iterator i = senders_.begin(); i != senders_.end();
548 ++i) { 518 ++i) {
549 if (i->first == sender && i->second == sender_route_id) 519 if (i->first == sender && i->second == sender_route_id)
550 return true; 520 return true;
551 } 521 }
552 return false; 522 return false;
553 } 523 }
554 524
525 bool WorkerProcessHost::WorkerInstance::RendererIsParent(
526 int renderer_id, int render_view_route_id) const {
527 const WorkerDocumentSet::DocumentInfoSet& parents =
528 worker_document_set()->documents();
529 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter =
530 parents.begin();
531 parent_iter != parents.end(); ++parent_iter) {
532 if (parent_iter->renderer_id() == renderer_id &&
533 parent_iter->render_view_route_id() == render_view_route_id) {
534 return true;
535 }
536 }
537 return false;
538 }
539
555 WorkerProcessHost::WorkerInstance::SenderInfo 540 WorkerProcessHost::WorkerInstance::SenderInfo
556 WorkerProcessHost::WorkerInstance::GetSender() const { 541 WorkerProcessHost::WorkerInstance::GetSender() const {
557 DCHECK(NumSenders() == 1); 542 DCHECK(NumSenders() == 1);
558 return *senders_.begin(); 543 return *senders_.begin();
559 } 544 }
OLDNEW
« no previous file with comments | « chrome/browser/worker_host/worker_process_host.h ('k') | chrome/browser/worker_host/worker_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698