OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |