| Index: chrome/browser/worker_host/worker_service.cc
|
| ===================================================================
|
| --- chrome/browser/worker_host/worker_service.cc (revision 69724)
|
| +++ chrome/browser/worker_host/worker_service.cc (working copy)
|
| @@ -11,13 +11,11 @@
|
| #include "base/sys_info.h"
|
| #include "base/thread.h"
|
| #include "chrome/browser/content_settings/host_content_settings_map.h"
|
| -#include "chrome/browser/plugin_service.h"
|
| -#include "chrome/browser/renderer_host/render_message_filter.h"
|
| -#include "chrome/browser/renderer_host/render_process_host.h"
|
| +#include "chrome/browser/worker_host/worker_message_filter.h"
|
| #include "chrome/browser/worker_host/worker_process_host.h"
|
| #include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/notification_service.h"
|
| #include "chrome/common/render_messages.h"
|
| +#include "chrome/common/render_messages_params.h"
|
| #include "chrome/common/worker_messages.h"
|
| #include "net/base/registry_controlled_domain.h"
|
|
|
| @@ -29,97 +27,205 @@
|
| return Singleton<WorkerService>::get();
|
| }
|
|
|
| -WorkerService::WorkerService()
|
| - : next_worker_route_id_(0),
|
| - resource_dispatcher_host_(NULL) {
|
| - // Receive a notification if a message filter or WorkerProcessHost is deleted.
|
| - registrar_.Add(this, NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN,
|
| - NotificationService::AllSources());
|
| -
|
| - registrar_.Add(this, NotificationType::WORKER_PROCESS_HOST_SHUTDOWN,
|
| - NotificationService::AllSources());
|
| +WorkerService::WorkerService() : next_worker_route_id_(0) {
|
| }
|
|
|
| -void WorkerService::Initialize(ResourceDispatcherHost* rdh) {
|
| - resource_dispatcher_host_ = rdh;
|
| -}
|
| -
|
| WorkerService::~WorkerService() {
|
| }
|
|
|
| -bool WorkerService::CreateDedicatedWorker(
|
| - const GURL& url,
|
| - bool is_off_the_record,
|
| - unsigned long long document_id,
|
| - int renderer_pid,
|
| - int render_view_route_id,
|
| - IPC::Message::Sender* sender,
|
| - int sender_route_id,
|
| - int parent_process_id,
|
| - int parent_appcache_host_id,
|
| - ChromeURLRequestContext* request_context) {
|
| - return CreateWorker(url, false, is_off_the_record, string16(),
|
| - document_id, renderer_pid, render_view_route_id,
|
| - sender, sender_route_id,
|
| - parent_process_id, parent_appcache_host_id, 0,
|
| - request_context);
|
| -}
|
| +void WorkerService::OnWorkerMessageFilterClosing(WorkerMessageFilter* filter) {
|
| + for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| + !iter.Done(); ++iter) {
|
| + WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| + worker->FilterShutdown(filter);
|
| + }
|
|
|
| -bool WorkerService::CreateSharedWorker(
|
| - const GURL& url,
|
| - bool is_off_the_record,
|
| - const string16& name,
|
| - unsigned long long document_id,
|
| - int renderer_pid,
|
| - int render_view_route_id,
|
| - IPC::Message::Sender* sender,
|
| - int sender_route_id,
|
| - int64 main_resource_appcache_id,
|
| - ChromeURLRequestContext* request_context) {
|
| - return CreateWorker(url, true, is_off_the_record, name,
|
| - document_id, renderer_pid, render_view_route_id,
|
| - sender, sender_route_id,
|
| - 0, 0, main_resource_appcache_id,
|
| - request_context);
|
| + // See if that process had any queued workers.
|
| + for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin();
|
| + i != queued_workers_.end();) {
|
| + i->RemoveFilters(filter);
|
| + if (i->NumFilters() == 0) {
|
| + i = queued_workers_.erase(i);
|
| + } else {
|
| + ++i;
|
| + }
|
| + }
|
| +
|
| + // Also, see if that process had any pending shared workers.
|
| + for (WorkerProcessHost::Instances::iterator iter =
|
| + pending_shared_workers_.begin();
|
| + iter != pending_shared_workers_.end(); ) {
|
| + iter->worker_document_set()->RemoveAll(filter);
|
| + if (iter->worker_document_set()->IsEmpty()) {
|
| + iter = pending_shared_workers_.erase(iter);
|
| + } else {
|
| + ++iter;
|
| + }
|
| + }
|
| +
|
| + // Either a worker proceess has shut down, in which case we can start one of
|
| + // the queued workers, or a renderer has shut down, in which case it doesn't
|
| + // affect anything. We call this function in both scenarios because then we
|
| + // don't have to keep track which filters are from worker processes.
|
| + TryStartingQueuedWorker();
|
| }
|
|
|
| -bool WorkerService::CreateWorker(
|
| - const GURL& url,
|
| - bool is_shared,
|
| - bool off_the_record,
|
| - const string16& name,
|
| - unsigned long long document_id,
|
| - int renderer_id,
|
| - int render_view_route_id,
|
| - IPC::Message::Sender* sender,
|
| - int sender_route_id,
|
| - int parent_process_id,
|
| - int parent_appcache_host_id,
|
| - int64 main_resource_appcache_id,
|
| - ChromeURLRequestContext* request_context) {
|
| +void WorkerService::CreateWorker(const ViewHostMsg_CreateWorker_Params& params,
|
| + int route_id,
|
| + WorkerMessageFilter* filter,
|
| + URLRequestContextGetter* request_context) {
|
| +
|
| + ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>(
|
| + request_context->GetURLRequestContext());
|
| +
|
| // Generate a unique route id for the browser-worker communication that's
|
| // unique among all worker processes. That way when the worker process sends
|
| // a wrapped IPC message through us, we know which WorkerProcessHost to give
|
| // it to.
|
| - WorkerProcessHost::WorkerInstance instance(url,
|
| - is_shared,
|
| - off_the_record,
|
| - name,
|
| - next_worker_route_id(),
|
| - parent_process_id,
|
| - parent_appcache_host_id,
|
| - main_resource_appcache_id,
|
| - request_context);
|
| - instance.AddSender(sender, sender_route_id);
|
| + WorkerProcessHost::WorkerInstance instance(
|
| + params.url,
|
| + params.is_shared,
|
| + context->is_off_the_record(),
|
| + params.name,
|
| + next_worker_route_id(),
|
| + params.is_shared ? 0 : filter->render_process_id(),
|
| + params.is_shared ? 0 : params.parent_appcache_host_id,
|
| + params.is_shared ? params.script_resource_appcache_id : 0,
|
| + request_context);
|
| + instance.AddFilter(filter, route_id);
|
| instance.worker_document_set()->Add(
|
| - sender, document_id, renderer_id, render_view_route_id);
|
| + filter, params.document_id, filter->render_process_id(),
|
| + params.render_view_route_id);
|
|
|
| - return CreateWorkerFromInstance(instance);
|
| + CreateWorkerFromInstance(instance);
|
| }
|
|
|
| +void WorkerService::LookupSharedWorker(
|
| + const ViewHostMsg_CreateWorker_Params& params,
|
| + int route_id,
|
| + WorkerMessageFilter* filter,
|
| + bool off_the_record,
|
| + bool* exists,
|
| + bool* url_mismatch) {
|
| +
|
| + *exists = true;
|
| + WorkerProcessHost::WorkerInstance* instance = FindSharedWorkerInstance(
|
| + params.url, params.name, off_the_record);
|
| +
|
| + if (!instance) {
|
| + // If no worker instance currently exists, we need to create a pending
|
| + // instance - this is to make sure that any subsequent lookups passing a
|
| + // mismatched URL get the appropriate url_mismatch error at lookup time.
|
| + // Having named shared workers was a Really Bad Idea due to details like
|
| + // this.
|
| + instance = CreatePendingInstance(params.url, params.name, off_the_record);
|
| + *exists = false;
|
| + }
|
| +
|
| + // Make sure the passed-in instance matches the URL - if not, return an
|
| + // error.
|
| + if (params.url != instance->url()) {
|
| + *url_mismatch = true;
|
| + *exists = false;
|
| + } else {
|
| + *url_mismatch = false;
|
| + // Add our route ID to the existing instance so we can send messages to it.
|
| + instance->AddFilter(filter, route_id);
|
| +
|
| + // Add the passed filter/document_id to the worker instance.
|
| + // TODO(atwilson): This won't work if the message is from a worker process.
|
| + // We don't support that yet though (this message is only sent from
|
| + // renderers) but when we do, we'll need to add code to pass in the current
|
| + // worker's document set for nested workers.
|
| + instance->worker_document_set()->Add(
|
| + filter, params.document_id, filter->render_process_id(),
|
| + params.render_view_route_id);
|
| + }
|
| +}
|
| +
|
| +void WorkerService::CancelCreateDedicatedWorker(
|
| + int route_id,
|
| + WorkerMessageFilter* filter) {
|
| + for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin();
|
| + i != queued_workers_.end(); ++i) {
|
| + if (i->HasFilter(filter, route_id)) {
|
| + DCHECK(!i->shared());
|
| + queued_workers_.erase(i);
|
| + return;
|
| + }
|
| + }
|
| +
|
| + // There could be a race condition where the WebWorkerProxy told us to cancel
|
| + // the worker right as we sent it a message say it's been created. Look at
|
| + // the running workers.
|
| + for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| + !iter.Done(); ++iter) {
|
| + WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| + for (WorkerProcessHost::Instances::const_iterator instance =
|
| + worker->instances().begin();
|
| + instance != worker->instances().end(); ++instance) {
|
| + if (instance->HasFilter(filter, route_id)) {
|
| + // Fake a worker destroyed message so that WorkerProcessHost cleans up
|
| + // properly.
|
| + WorkerHostMsg_WorkerContextDestroyed message(route_id);
|
| + ForwardToWorker(message, filter);
|
| + return;
|
| + }
|
| + }
|
| + }
|
| +
|
| + DCHECK(false) << "Couldn't find worker to cancel";
|
| +}
|
| +
|
| +void WorkerService::ForwardToWorker(const IPC::Message& message,
|
| + WorkerMessageFilter* filter) {
|
| + for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| + !iter.Done(); ++iter) {
|
| + WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| + if (worker->FilterMessage(message, filter))
|
| + return;
|
| + }
|
| +
|
| + // TODO(jabdelmalek): tell filter that callee is gone
|
| +}
|
| +
|
| +void WorkerService::DocumentDetached(unsigned long long document_id,
|
| + WorkerMessageFilter* filter) {
|
| + // Any associated shared workers can be shut down.
|
| + for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| + !iter.Done(); ++iter) {
|
| + WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| + worker->DocumentDetached(filter, document_id);
|
| + }
|
| +
|
| + // Remove any queued shared workers for this document.
|
| + for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin();
|
| + iter != queued_workers_.end();) {
|
| + if (iter->shared()) {
|
| + iter->worker_document_set()->Remove(filter, document_id);
|
| + if (iter->worker_document_set()->IsEmpty()) {
|
| + iter = queued_workers_.erase(iter);
|
| + continue;
|
| + }
|
| + }
|
| + ++iter;
|
| + }
|
| +
|
| + // Remove the document from any pending shared workers.
|
| + for (WorkerProcessHost::Instances::iterator iter =
|
| + pending_shared_workers_.begin();
|
| + iter != pending_shared_workers_.end(); ) {
|
| + iter->worker_document_set()->Remove(filter, document_id);
|
| + if (iter->worker_document_set()->IsEmpty()) {
|
| + iter = pending_shared_workers_.erase(iter);
|
| + } else {
|
| + ++iter;
|
| + }
|
| + }
|
| +}
|
| +
|
| bool WorkerService::CreateWorkerFromInstance(
|
| WorkerProcessHost::WorkerInstance instance) {
|
| -
|
| // TODO(michaeln): We need to ensure that a process is working
|
| // on behalf of a single profile. The process sharing logic below
|
| // does not ensure that. Consider making WorkerService a per profile
|
| @@ -145,17 +251,17 @@
|
| WorkerProcessHost::WorkerInstance* existing_instance =
|
| FindSharedWorkerInstance(
|
| instance.url(), instance.name(), instance.off_the_record());
|
| - WorkerProcessHost::WorkerInstance::SenderInfo sender_info =
|
| - instance.GetSender();
|
| + WorkerProcessHost::WorkerInstance::FilterInfo filter_info =
|
| + instance.GetFilter();
|
| // If this worker is already running, no need to create a new copy. Just
|
| // inform the caller that the worker has been created.
|
| if (existing_instance) {
|
| - // Walk the worker's sender list to see if this client is listed. If not,
|
| + // Walk the worker's filter list to see if this client is listed. If not,
|
| // then it means that the worker started by the client already exited so
|
| // we should not attach to this new one (http://crbug.com/29243).
|
| - if (!existing_instance->HasSender(sender_info.first, sender_info.second))
|
| + if (!existing_instance->HasFilter(filter_info.first, filter_info.second))
|
| return false;
|
| - sender_info.first->Send(new ViewMsg_WorkerCreated(sender_info.second));
|
| + filter_info.first->Send(new ViewMsg_WorkerCreated(filter_info.second));
|
| return true;
|
| }
|
|
|
| @@ -163,38 +269,38 @@
|
| WorkerProcessHost::WorkerInstance* pending = FindPendingInstance(
|
| instance.url(), instance.name(), instance.off_the_record());
|
| // If there's no instance *and* no pending instance (or there is a pending
|
| - // instance but it does not contain our sender info), then it means the
|
| + // instance but it does not contain our filter info), then it means the
|
| // worker started up and exited already. Log a warning because this should
|
| // be a very rare occurrence and is probably a bug, but it *can* happen so
|
| // handle it gracefully.
|
| if (!pending ||
|
| - !pending->HasSender(sender_info.first, sender_info.second)) {
|
| + !pending->HasFilter(filter_info.first, filter_info.second)) {
|
| DLOG(WARNING) << "Pending worker already exited";
|
| return false;
|
| }
|
|
|
| - // Assign the accumulated document set and sender list for this pending
|
| + // Assign the accumulated document set and filter list for this pending
|
| // worker to the new instance.
|
| DCHECK(!pending->worker_document_set()->IsEmpty());
|
| instance.ShareDocumentSet(*pending);
|
| - for (WorkerProcessHost::WorkerInstance::SenderList::const_iterator i =
|
| - pending->senders().begin();
|
| - i != pending->senders().end(); ++i) {
|
| - instance.AddSender(i->first, i->second);
|
| + for (WorkerProcessHost::WorkerInstance::FilterList::const_iterator i =
|
| + pending->filters().begin();
|
| + i != pending->filters().end(); ++i) {
|
| + instance.AddFilter(i->first, i->second);
|
| }
|
| RemovePendingInstances(
|
| instance.url(), instance.name(), instance.off_the_record());
|
|
|
| - // Remove any queued instances of this worker and copy over the sender to
|
| + // Remove any queued instances of this worker and copy over the filter to
|
| // this instance.
|
| for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin();
|
| iter != queued_workers_.end();) {
|
| if (iter->Matches(instance.url(), instance.name(),
|
| instance.off_the_record())) {
|
| - DCHECK(iter->NumSenders() == 1);
|
| - WorkerProcessHost::WorkerInstance::SenderInfo sender_info =
|
| - iter->GetSender();
|
| - instance.AddSender(sender_info.first, sender_info.second);
|
| + DCHECK(iter->NumFilters() == 1);
|
| + WorkerProcessHost::WorkerInstance::FilterInfo filter_info =
|
| + iter->GetFilter();
|
| + instance.AddFilter(filter_info.first, filter_info.second);
|
| iter = queued_workers_.erase(iter);
|
| } else {
|
| ++iter;
|
| @@ -203,9 +309,15 @@
|
| }
|
|
|
| if (!worker) {
|
| - worker = new WorkerProcessHost(resource_dispatcher_host_,
|
| - instance.request_context());
|
| - if (!worker->Init()) {
|
| + WorkerMessageFilter* first_filter = instance.filters().begin()->first;
|
| + worker = new WorkerProcessHost(
|
| + first_filter->resource_dispatcher_host(),
|
| + instance.request_context());
|
| + // TODO(atwilson): This won't work if the message is from a worker process.
|
| + // We don't support that yet though (this message is only sent from
|
| + // renderers) but when we do, we'll need to add code to pass in the current
|
| + // worker's document set for nested workers.
|
| + if (!worker->Init(first_filter->render_process_id())) {
|
| delete worker;
|
| return false;
|
| }
|
| @@ -219,127 +331,6 @@
|
| return true;
|
| }
|
|
|
| -bool WorkerService::LookupSharedWorker(
|
| - const GURL &url,
|
| - const string16& name,
|
| - bool off_the_record,
|
| - unsigned long long document_id,
|
| - int renderer_id,
|
| - int render_view_route_id,
|
| - IPC::Message::Sender* sender,
|
| - int sender_route_id,
|
| - bool* url_mismatch) {
|
| - bool found_instance = true;
|
| - WorkerProcessHost::WorkerInstance* instance =
|
| - FindSharedWorkerInstance(url, name, off_the_record);
|
| -
|
| - if (!instance) {
|
| - // If no worker instance currently exists, we need to create a pending
|
| - // instance - this is to make sure that any subsequent lookups passing a
|
| - // mismatched URL get the appropriate url_mismatch error at lookup time.
|
| - // Having named shared workers was a Really Bad Idea due to details like
|
| - // this.
|
| - instance = CreatePendingInstance(url, name, off_the_record);
|
| - found_instance = false;
|
| - }
|
| -
|
| - // Make sure the passed-in instance matches the URL - if not, return an
|
| - // error.
|
| - if (url != instance->url()) {
|
| - *url_mismatch = true;
|
| - return false;
|
| - } else {
|
| - *url_mismatch = false;
|
| - }
|
| -
|
| - // Add our route ID to the existing instance so we can send messages to it.
|
| - instance->AddSender(sender, sender_route_id);
|
| -
|
| - // Add the passed sender/document_id to the worker instance.
|
| - instance->worker_document_set()->Add(
|
| - sender, document_id, renderer_id, render_view_route_id);
|
| - return found_instance;
|
| -}
|
| -
|
| -void WorkerService::DocumentDetached(IPC::Message::Sender* sender,
|
| - unsigned long long document_id) {
|
| - for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| - !iter.Done(); ++iter) {
|
| - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| - worker->DocumentDetached(sender, document_id);
|
| - }
|
| -
|
| - // Remove any queued shared workers for this document.
|
| - for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin();
|
| - iter != queued_workers_.end();) {
|
| - if (iter->shared()) {
|
| - iter->worker_document_set()->Remove(sender, document_id);
|
| - if (iter->worker_document_set()->IsEmpty()) {
|
| - iter = queued_workers_.erase(iter);
|
| - continue;
|
| - }
|
| - }
|
| - ++iter;
|
| - }
|
| -
|
| - // Remove the document from any pending shared workers.
|
| - for (WorkerProcessHost::Instances::iterator iter =
|
| - pending_shared_workers_.begin();
|
| - iter != pending_shared_workers_.end(); ) {
|
| - iter->worker_document_set()->Remove(sender, document_id);
|
| - if (iter->worker_document_set()->IsEmpty()) {
|
| - iter = pending_shared_workers_.erase(iter);
|
| - } else {
|
| - ++iter;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void WorkerService::CancelCreateDedicatedWorker(IPC::Message::Sender* sender,
|
| - int sender_route_id) {
|
| - for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin();
|
| - i != queued_workers_.end(); ++i) {
|
| - if (i->HasSender(sender, sender_route_id)) {
|
| - DCHECK(!i->shared());
|
| - queued_workers_.erase(i);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - // There could be a race condition where the WebWorkerProxy told us to cancel
|
| - // the worker right as we sent it a message say it's been created. Look at
|
| - // the running workers.
|
| - for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| - !iter.Done(); ++iter) {
|
| - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| - for (WorkerProcessHost::Instances::const_iterator instance =
|
| - worker->instances().begin();
|
| - instance != worker->instances().end(); ++instance) {
|
| - if (instance->HasSender(sender, sender_route_id)) {
|
| - // Fake a worker destroyed message so that WorkerProcessHost cleans up
|
| - // properly.
|
| - WorkerHostMsg_WorkerContextDestroyed msg(sender_route_id);
|
| - ForwardMessage(msg, sender);
|
| - return;
|
| - }
|
| - }
|
| - }
|
| -
|
| - DCHECK(false) << "Couldn't find worker to cancel";
|
| -}
|
| -
|
| -void WorkerService::ForwardMessage(const IPC::Message& message,
|
| - IPC::Message::Sender* sender) {
|
| - for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| - !iter.Done(); ++iter) {
|
| - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| - if (worker->FilterMessage(message, sender))
|
| - return;
|
| - }
|
| -
|
| - // TODO(jabdelmalek): tell sender that callee is gone
|
| -}
|
| -
|
| WorkerProcessHost* WorkerService::GetProcessForDomain(const GURL& url) {
|
| int num_processes = 0;
|
| std::string domain =
|
| @@ -398,8 +389,8 @@
|
| parents.begin();
|
| parent_iter != parents.end(); ++parent_iter) {
|
| bool hit_total_worker_limit = false;
|
| - if (TabCanCreateWorkerProcess(parent_iter->renderer_id(),
|
| - parent_iter->render_view_route_id(),
|
| + if (TabCanCreateWorkerProcess(parent_iter->render_process_id(),
|
| + parent_iter->render_view_id(),
|
| &hit_total_worker_limit)) {
|
| return true;
|
| }
|
| @@ -413,8 +404,8 @@
|
| return false;
|
| }
|
|
|
| -bool WorkerService::TabCanCreateWorkerProcess(int renderer_id,
|
| - int render_view_route_id,
|
| +bool WorkerService::TabCanCreateWorkerProcess(int render_process_id,
|
| + int render_view_id,
|
| bool* hit_total_worker_limit) {
|
| int total_workers = 0;
|
| int workers_per_tab = 0;
|
| @@ -430,7 +421,7 @@
|
| *hit_total_worker_limit = true;
|
| return false;
|
| }
|
| - if (cur_instance->RendererIsParent(renderer_id, render_view_route_id)) {
|
| + if (cur_instance->RendererIsParent(render_process_id, render_view_id)) {
|
| workers_per_tab++;
|
| if (workers_per_tab >= kMaxWorkersPerTabWhenSeparate)
|
| return false;
|
| @@ -441,53 +432,7 @@
|
| return true;
|
| }
|
|
|
| -void WorkerService::Observe(NotificationType type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - if (type.value == NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN) {
|
| - RenderMessageFilter* sender = Source<RenderMessageFilter>(source).ptr();
|
| - SenderShutdown(sender);
|
| - } else if (type.value == NotificationType::WORKER_PROCESS_HOST_SHUTDOWN) {
|
| - WorkerProcessHost* sender = Source<WorkerProcessHost>(source).ptr();
|
| - SenderShutdown(sender);
|
| - WorkerProcessDestroyed(sender);
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -}
|
| -
|
| -void WorkerService::SenderShutdown(IPC::Message::Sender* sender) {
|
| - for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| - !iter.Done(); ++iter) {
|
| - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| - worker->SenderShutdown(sender);
|
| - }
|
| -
|
| - // See if that render process had any queued workers.
|
| - for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin();
|
| - i != queued_workers_.end();) {
|
| - i->RemoveSenders(sender);
|
| - if (i->NumSenders() == 0) {
|
| - i = queued_workers_.erase(i);
|
| - } else {
|
| - ++i;
|
| - }
|
| - }
|
| -
|
| - // Also, see if that render process had any pending shared workers.
|
| - for (WorkerProcessHost::Instances::iterator iter =
|
| - pending_shared_workers_.begin();
|
| - iter != pending_shared_workers_.end(); ) {
|
| - iter->worker_document_set()->RemoveAll(sender);
|
| - if (iter->worker_document_set()->IsEmpty()) {
|
| - iter = pending_shared_workers_.erase(iter);
|
| - } else {
|
| - ++iter;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void WorkerService::WorkerProcessDestroyed(WorkerProcessHost* process) {
|
| +void WorkerService::TryStartingQueuedWorker() {
|
| if (queued_workers_.empty())
|
| return;
|
|
|
| @@ -510,6 +455,30 @@
|
| }
|
| }
|
|
|
| +bool WorkerService::GetRendererForWorker(int worker_process_id,
|
| + int* render_process_id,
|
| + int* render_view_id) const {
|
| + for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
| + !iter.Done(); ++iter) {
|
| + if (iter->id() != worker_process_id)
|
| + continue;
|
| +
|
| + // This code assumes one worker per process, see function comment in header!
|
| + WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
|
| + WorkerProcessHost::Instances::const_iterator first_instance =
|
| + worker->instances().begin();
|
| + if (first_instance == worker->instances().end())
|
| + return false;
|
| +
|
| + WorkerDocumentSet::DocumentInfoSet::const_iterator info =
|
| + first_instance->worker_document_set()->documents().begin();
|
| + *render_process_id = info->render_process_id();
|
| + *render_view_id = info->render_view_id();
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| const WorkerProcessHost::WorkerInstance* WorkerService::FindWorkerInstance(
|
| int worker_process_id) {
|
| for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
|
|
|