X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fcontent%2Fbrowser%2Fworker_host%2Fworker_service_impl.cc;h=f2ac3735ae789c4dca1d7338ad2d67c6510d52c0;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=15215ee68316860576e263d269548fb4df801c98;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/content/browser/worker_host/worker_service_impl.cc b/src/content/browser/worker_host/worker_service_impl.cc index 15215ee..f2ac373 100644 --- a/src/content/browser/worker_host/worker_service_impl.cc +++ b/src/content/browser/worker_host/worker_service_impl.cc @@ -268,29 +268,6 @@ void WorkerServiceImpl::OnWorkerMessageFilterClosing( } } - for (WorkerProcessHost::Instances::iterator i = - pending_shared_workers_.begin(); - i != pending_shared_workers_.end(); ) { - i->RemoveFilters(filter); - if (i->NumFilters() == 0) { - i = pending_shared_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 @@ -303,8 +280,38 @@ void WorkerServiceImpl::CreateWorker( int route_id, WorkerMessageFilter* filter, ResourceContext* resource_context, - const WorkerStoragePartition& partition) { + const WorkerStoragePartition& partition, + bool* url_mismatch) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + *url_mismatch = false; + WorkerProcessHost::WorkerInstance* existing_instance = + FindSharedWorkerInstance( + params.url, params.name, partition, resource_context); + if (existing_instance) { + if (params.url != existing_instance->url()) { + *url_mismatch = true; + return; + } + if (existing_instance->load_failed()) { + filter->Send(new ViewMsg_WorkerScriptLoadFailed(route_id)); + return; + } + existing_instance->AddFilter(filter, route_id); + existing_instance->worker_document_set()->Add( + filter, params.document_id, filter->render_process_id(), + params.render_frame_route_id); + filter->Send(new ViewMsg_WorkerCreated(route_id)); + return; + } + for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin(); + i != queued_workers_.end(); ++i) { + if (i->Matches(params.url, params.name, partition, resource_context) && + params.url != i->url()) { + *url_mismatch = true; + return; + } + } + // 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 @@ -315,8 +322,7 @@ void WorkerServiceImpl::CreateWorker( params.content_security_policy, params.security_policy_type, next_worker_route_id(), - 0, - params.script_resource_appcache_id, + params.render_frame_route_id, resource_context, partition); instance.AddFilter(filter, route_id); @@ -327,50 +333,6 @@ void WorkerServiceImpl::CreateWorker( CreateWorkerFromInstance(instance); } -void WorkerServiceImpl::LookupSharedWorker( - const ViewHostMsg_CreateWorker_Params& params, - int route_id, - WorkerMessageFilter* filter, - ResourceContext* resource_context, - const WorkerStoragePartition& partition, - bool* exists, - bool* url_mismatch) { - *exists = true; - WorkerProcessHost::WorkerInstance* instance = FindSharedWorkerInstance( - params.url, params.name, partition, resource_context); - - 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, - resource_context, partition); - *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_frame_route_id); - } -} - void WorkerServiceImpl::ForwardToWorker(const IPC::Message& message, WorkerMessageFilter* filter) { for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { @@ -398,18 +360,6 @@ void WorkerServiceImpl::DocumentDetached(unsigned long long document_id, } ++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 WorkerServiceImpl::CreateWorkerFromInstance( @@ -419,54 +369,6 @@ bool WorkerServiceImpl::CreateWorkerFromInstance( return true; } - // Check to see if this shared worker is already running (two pages may have - // tried to start up the worker simultaneously). - // See if a worker with this name already exists. - WorkerProcessHost::WorkerInstance* existing_instance = - FindSharedWorkerInstance( - instance.url(), instance.name(), instance.partition(), - instance.resource_context()); - 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 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->HasFilter(filter_info.first, filter_info.second)) - return false; - filter_info.first->Send(new ViewMsg_WorkerCreated(filter_info.second)); - return true; - } - - // Look to see if there's a pending instance. - WorkerProcessHost::WorkerInstance* pending = FindPendingInstance( - instance.url(), instance.name(), instance.partition(), - instance.resource_context()); - // If there's no instance *and* no pending instance (or there is a pending - // 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->HasFilter(filter_info.first, filter_info.second)) { - DLOG(WARNING) << "Pending worker already exited"; - return false; - } - - // 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::FilterList::const_iterator i = - pending->filters().begin(); - i != pending->filters().end(); ++i) { - instance.AddFilter(i->first, i->second); - } - RemovePendingInstances(instance.url(), instance.name(), - instance.partition(), instance.resource_context()); - // Remove any queued instances of this worker and copy over the filter to // this instance. for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); @@ -474,23 +376,25 @@ bool WorkerServiceImpl::CreateWorkerFromInstance( if (iter->Matches(instance.url(), instance.name(), instance.partition(), instance.resource_context())) { DCHECK(iter->NumFilters() == 1); + DCHECK_EQ(instance.url(), iter->url()); WorkerProcessHost::WorkerInstance::FilterInfo filter_info = iter->GetFilter(); - instance.AddFilter(filter_info.first, filter_info.second); + instance.AddFilter(filter_info.filter(), filter_info.route_id()); iter = queued_workers_.erase(iter); } else { ++iter; } } - WorkerMessageFilter* first_filter = instance.filters().begin()->first; + WorkerMessageFilter* first_filter = instance.filters().begin()->filter(); WorkerProcessHost* worker = new WorkerProcessHost( instance.resource_context(), instance.partition()); // 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())) { + if (!worker->Init(first_filter->render_process_id(), + instance.render_frame_id())) { delete worker; return false; } @@ -682,56 +586,4 @@ WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance( return NULL; } -WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindPendingInstance( - const GURL& url, - const base::string16& name, - const WorkerStoragePartition& partition, - ResourceContext* resource_context) { - // Walk the pending instances looking for a matching pending worker. - for (WorkerProcessHost::Instances::iterator iter = - pending_shared_workers_.begin(); - iter != pending_shared_workers_.end(); - ++iter) { - if (iter->Matches(url, name, partition, resource_context)) - return &(*iter); - } - return NULL; -} - - -void WorkerServiceImpl::RemovePendingInstances( - const GURL& url, - const base::string16& name, - const WorkerStoragePartition& partition, - ResourceContext* resource_context) { - // Walk the pending instances looking for a matching pending worker. - for (WorkerProcessHost::Instances::iterator iter = - pending_shared_workers_.begin(); - iter != pending_shared_workers_.end(); ) { - if (iter->Matches(url, name, partition, resource_context)) { - iter = pending_shared_workers_.erase(iter); - } else { - ++iter; - } - } -} - -WorkerProcessHost::WorkerInstance* WorkerServiceImpl::CreatePendingInstance( - const GURL& url, - const base::string16& name, - ResourceContext* resource_context, - const WorkerStoragePartition& partition) { - // Look for an existing pending shared worker. - WorkerProcessHost::WorkerInstance* instance = - FindPendingInstance(url, name, partition, resource_context); - if (instance) - return instance; - - // No existing pending worker - create a new one. - WorkerProcessHost::WorkerInstance pending( - url, true, name, resource_context, partition); - pending_shared_workers_.push_back(pending); - return &pending_shared_workers_.back(); -} - } // namespace content