diff options
author | horo@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-05 06:04:58 +0000 |
---|---|---|
committer | horo@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-05 06:04:58 +0000 |
commit | d8f7d16ef3379f82b624f8256ab066045bba28d6 (patch) | |
tree | f5400ce1c5ca89b76409e5004468d35ff8e1050f | |
parent | 415f99b18e6f14c53e08f6574a3bc653049fbaae (diff) | |
download | chromium_src-d8f7d16ef3379f82b624f8256ab066045bba28d6.zip chromium_src-d8f7d16ef3379f82b624f8256ab066045bba28d6.tar.gz chromium_src-d8f7d16ef3379f82b624f8256ab066045bba28d6.tar.bz2 |
Move the worker script loading code to the worker process (phase:4/5)
- Stop sending the worker script from the renderer.
- In this change we can remove the pending instances in WorkerServiceImpl.
This is step 4 of moving the worker script loading code from the renderer process to the worker process.
See: http://crbug.com/329786
BUG=329786
Review URL: https://codereview.chromium.org/133093003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@248869 0039d316-1c4b-4281-b951-d872f2087c98
18 files changed, 236 insertions, 521 deletions
diff --git a/content/browser/worker_host/worker_message_filter.cc b/content/browser/worker_host/worker_message_filter.cc index 49fe7f6..b332094 100644 --- a/content/browser/worker_host/worker_message_filter.cc +++ b/content/browser/worker_host/worker_message_filter.cc @@ -40,8 +40,6 @@ bool WorkerMessageFilter::OnMessageReceived(const IPC::Message& message, // Worker messages. // Only sent from renderer for now, until we have nested workers. IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWorker, OnCreateWorker) - // Only sent from renderer for now, until we have nested workers. - IPC_MESSAGE_HANDLER(ViewHostMsg_LookupSharedWorker, OnLookupSharedWorker) IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToWorker, OnForwardToWorker) // Only sent from renderer. IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentDetached, OnDocumentDetached) @@ -58,22 +56,12 @@ int WorkerMessageFilter::GetNextRoutingID() { void WorkerMessageFilter::OnCreateWorker( const ViewHostMsg_CreateWorker_Params& params, int* route_id) { - *route_id = params.route_id != MSG_ROUTING_NONE ? - params.route_id : GetNextRoutingID(); - WorkerServiceImpl::GetInstance()->CreateWorker( - params, *route_id, this, resource_context_, partition_); -} - -void WorkerMessageFilter::OnLookupSharedWorker( - const ViewHostMsg_CreateWorker_Params& params, - bool* exists, - int* route_id, - bool* url_error) { + bool url_error = false; *route_id = GetNextRoutingID(); - - WorkerServiceImpl::GetInstance()->LookupSharedWorker( - params, *route_id, this, resource_context_, partition_, exists, - url_error); + WorkerServiceImpl::GetInstance()->CreateWorker( + params, *route_id, this, resource_context_, partition_, &url_error); + if (url_error) + *route_id = MSG_ROUTING_NONE; } void WorkerMessageFilter::OnForwardToWorker(const IPC::Message& message) { diff --git a/content/browser/worker_host/worker_message_filter.h b/content/browser/worker_host/worker_message_filter.h index 0d495fa..7581936 100644 --- a/content/browser/worker_host/worker_message_filter.h +++ b/content/browser/worker_host/worker_message_filter.h @@ -41,10 +41,6 @@ class WorkerMessageFilter : public BrowserMessageFilter { // Message handlers. void OnCreateWorker(const ViewHostMsg_CreateWorker_Params& params, int* route_id); - void OnLookupSharedWorker(const ViewHostMsg_CreateWorker_Params& params, - bool* exists, - int* route_id, - bool* url_error); void OnForwardToWorker(const IPC::Message& message); void OnDocumentDetached(unsigned long long document_id); void OnCreateMessagePort(int* route_id, int* message_port_id); diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc index 2ba32e2..d672028e 100644 --- a/content/browser/worker_host/worker_process_host.cc +++ b/content/browser/worker_host/worker_process_host.cc @@ -130,14 +130,16 @@ WorkerProcessHost::WorkerProcessHost( WorkerProcessHost::~WorkerProcessHost() { // If we crashed, tell the RenderViewHosts. for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { - const WorkerDocumentSet::DocumentInfoSet& parents = - i->worker_document_set()->documents(); - for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = - parents.begin(); parent_iter != parents.end(); ++parent_iter) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&WorkerCrashCallback, parent_iter->render_process_id(), - parent_iter->render_frame_id())); + if (!i->load_failed()) { + const WorkerDocumentSet::DocumentInfoSet& parents = + i->worker_document_set()->documents(); + for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = + parents.begin(); parent_iter != parents.end(); ++parent_iter) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&WorkerCrashCallback, parent_iter->render_process_id(), + parent_iter->render_frame_id())); + } } WorkerServiceImpl::GetInstance()->NotifyWorkerDestroyed( this, i->worker_route_id()); @@ -317,8 +319,6 @@ void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) { params.content_security_policy = instance.content_security_policy(); params.security_policy_type = instance.security_policy_type(); params.route_id = instance.worker_route_id(); - params.creator_process_id = instance.parent_process_id(); - params.shared_worker_appcache_id = instance.main_resource_appcache_id(); Send(new WorkerProcessMsg_CreateWorker(params)); UpdateTitle(); @@ -329,8 +329,7 @@ void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) { for (WorkerInstance::FilterList::const_iterator i = instance.filters().begin(); i != instance.filters().end(); ++i) { - CHECK(i->first); - i->first->Send(new ViewMsg_WorkerCreated(i->second)); + i->filter()->Send(new ViewMsg_WorkerCreated(i->route_id())); } } @@ -338,7 +337,7 @@ bool WorkerProcessHost::FilterMessage(const IPC::Message& message, WorkerMessageFilter* filter) { for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { if (!i->closed() && i->HasFilter(filter, message.routing_id())) { - RelayMessage(message, worker_message_filter_.get(), i->worker_route_id()); + RelayMessage(message, filter, &(*i)); return true; } } @@ -358,6 +357,12 @@ bool WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP_EX(WorkerProcessHost, message, msg_is_ok) IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerContextClosed, OnWorkerContextClosed) + IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerScriptLoaded, + OnWorkerScriptLoaded) + IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerScriptLoadFailed, + OnWorkerScriptLoadFailed) + IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerConnected, + OnWorkerConnected) IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_AllowDatabase, OnAllowDatabase) IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_AllowFileSystem, OnAllowFileSystem) IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_AllowIndexedDB, OnAllowIndexedDB) @@ -407,6 +412,45 @@ void WorkerProcessHost::OnWorkerContextClosed(int worker_route_id) { } } +void WorkerProcessHost::OnWorkerScriptLoaded(int worker_route_id) { + WorkerDevToolsManager::GetInstance()->WorkerContextStarted(this, + worker_route_id); +} + +void WorkerProcessHost::OnWorkerScriptLoadFailed(int worker_route_id) { + bool shutdown = true; + for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { + if (i->worker_route_id() != worker_route_id) { + shutdown = false; + continue; + } + i->set_load_failed(true); + for (WorkerInstance::FilterList::const_iterator j = i->filters().begin(); + j != i->filters().end(); ++j) { + j->filter()->Send(new ViewMsg_WorkerScriptLoadFailed(j->route_id())); + } + } + if (shutdown) { + base::KillProcess( + process_->GetData().handle, RESULT_CODE_NORMAL_EXIT, false); + } +} + +void WorkerProcessHost::OnWorkerConnected(int message_port_id, + int worker_route_id) { + for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { + if (i->worker_route_id() != worker_route_id) + continue; + for (WorkerInstance::FilterList::const_iterator j = i->filters().begin(); + j != i->filters().end(); ++j) { + if (j->message_port_id() != message_port_id) + continue; + j->filter()->Send(new ViewMsg_WorkerConnected(j->route_id())); + return; + } + } +} + void WorkerProcessHost::OnAllowDatabase(int worker_route_id, const GURL& url, const base::string16& name, @@ -444,8 +488,8 @@ void WorkerProcessHost::OnForceKillWorkerProcess() { void WorkerProcessHost::RelayMessage( const IPC::Message& message, - WorkerMessageFilter* filter, - int route_id) { + WorkerMessageFilter* incoming_filter, + WorkerInstance* instance) { if (message.type() == WorkerMsg_Connect::ID) { // Crack the SharedWorker Connect message to setup routing for the port. int sent_message_port_id; @@ -454,27 +498,26 @@ void WorkerProcessHost::RelayMessage( &message, &sent_message_port_id, &new_routing_id)) { return; } - new_routing_id = filter->GetNextRoutingID(); + new_routing_id = worker_message_filter_->GetNextRoutingID(); MessagePortService::GetInstance()->UpdateMessagePort( sent_message_port_id, - filter->message_port_message_filter(), + worker_message_filter_->message_port_message_filter(), new_routing_id); + instance->SetMessagePortID(incoming_filter, + message.routing_id(), + sent_message_port_id); // Resend the message with the new routing id. - filter->Send(new WorkerMsg_Connect( - route_id, sent_message_port_id, new_routing_id)); + worker_message_filter_->Send(new WorkerMsg_Connect( + instance->worker_route_id(), sent_message_port_id, new_routing_id)); // Send any queued messages for the sent port. MessagePortService::GetInstance()->SendQueuedMessagesIfPossible( sent_message_port_id); } else { IPC::Message* new_message = new IPC::Message(message); - new_message->set_routing_id(route_id); - filter->Send(new_message); - if (message.type() == WorkerMsg_StartWorkerContext::ID) { - WorkerDevToolsManager::GetInstance()->WorkerContextStarted( - this, route_id); - } + new_message->set_routing_id(instance->worker_route_id()); + worker_message_filter_->Send(new_message); return; } } @@ -646,9 +689,7 @@ WorkerProcessHost::WorkerInstance::WorkerInstance( const base::string16& content_security_policy, blink::WebContentSecurityPolicyType security_policy_type, int worker_route_id, - int parent_process_id, int render_frame_id, - int64 main_resource_appcache_id, ResourceContext* resource_context, const WorkerStoragePartition& partition) : url_(url), @@ -657,34 +698,27 @@ WorkerProcessHost::WorkerInstance::WorkerInstance( content_security_policy_(content_security_policy), security_policy_type_(security_policy_type), worker_route_id_(worker_route_id), - parent_process_id_(parent_process_id), render_frame_id_(render_frame_id), - main_resource_appcache_id_(main_resource_appcache_id), worker_document_set_(new WorkerDocumentSet()), resource_context_(resource_context), - partition_(partition) { + partition_(partition), + load_failed_(false) { DCHECK(resource_context_); } -WorkerProcessHost::WorkerInstance::WorkerInstance( - const GURL& url, - bool shared, - const base::string16& name, - ResourceContext* resource_context, - const WorkerStoragePartition& partition) - : url_(url), - closed_(false), - name_(name), - worker_route_id_(MSG_ROUTING_NONE), - parent_process_id_(0), - main_resource_appcache_id_(0), - worker_document_set_(new WorkerDocumentSet()), - resource_context_(resource_context), - partition_(partition) { - DCHECK(resource_context_); +WorkerProcessHost::WorkerInstance::~WorkerInstance() { } -WorkerProcessHost::WorkerInstance::~WorkerInstance() { +void WorkerProcessHost::WorkerInstance::SetMessagePortID( + WorkerMessageFilter* filter, + int route_id, + int message_port_id) { + for (FilterList::iterator i = filters_.begin(); i != filters_.end(); ++i) { + if (i->filter() == filter && i->route_id() == route_id) { + i->set_message_port_id(message_port_id); + return; + } + } } // Compares an instance based on the algorithm in the WebWorkers spec - an @@ -732,7 +766,7 @@ void WorkerProcessHost::WorkerInstance::AddFilter(WorkerMessageFilter* filter, void WorkerProcessHost::WorkerInstance::RemoveFilter( WorkerMessageFilter* filter, int route_id) { for (FilterList::iterator i = filters_.begin(); i != filters_.end();) { - if (i->first == filter && i->second == route_id) + if (i->filter() == filter && i->route_id() == route_id) i = filters_.erase(i); else ++i; @@ -744,7 +778,7 @@ void WorkerProcessHost::WorkerInstance::RemoveFilter( void WorkerProcessHost::WorkerInstance::RemoveFilters( WorkerMessageFilter* filter) { for (FilterList::iterator i = filters_.begin(); i != filters_.end();) { - if (i->first == filter) + if (i->filter() == filter) i = filters_.erase(i); else ++i; @@ -755,7 +789,7 @@ bool WorkerProcessHost::WorkerInstance::HasFilter( WorkerMessageFilter* filter, int route_id) const { for (FilterList::const_iterator i = filters_.begin(); i != filters_.end(); ++i) { - if (i->first == filter && i->second == route_id) + if (i->filter() == filter && i->route_id() == route_id) return true; } return false; diff --git a/content/browser/worker_host/worker_process_host.h b/content/browser/worker_host/worker_process_host.h index b555313..2a70637 100644 --- a/content/browser/worker_host/worker_process_host.h +++ b/content/browser/worker_host/worker_process_host.h @@ -62,21 +62,26 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate, const base::string16& content_security_policy, blink::WebContentSecurityPolicyType security_policy_type, int worker_route_id, - int parent_process_id, int render_frame_id, - int64 main_resource_appcache_id, - ResourceContext* resource_context, - const WorkerStoragePartition& partition); - // Used for pending instances. Rest of the parameters are ignored. - WorkerInstance(const GURL& url, - bool shared, - const base::string16& name, ResourceContext* resource_context, const WorkerStoragePartition& partition); ~WorkerInstance(); // Unique identifier for a worker client. - typedef std::pair<WorkerMessageFilter*, int> FilterInfo; + class FilterInfo { + public: + FilterInfo(WorkerMessageFilter* filter, int route_id) + : filter_(filter), route_id_(route_id), message_port_id_(0) { } + WorkerMessageFilter* filter() const { return filter_; } + int route_id() const { return route_id_; } + int message_port_id() const { return message_port_id_; } + void set_message_port_id(int id) { message_port_id_ = id; } + + private: + WorkerMessageFilter* filter_; + int route_id_; + int message_port_id_; + }; // APIs to manage the filter list for a given instance. void AddFilter(WorkerMessageFilter* filter, int route_id); @@ -85,6 +90,9 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate, bool HasFilter(WorkerMessageFilter* filter, int route_id) const; bool FrameIsParent(int render_process_id, int render_frame_id) const; int NumFilters() const { return filters_.size(); } + void SetMessagePortID(WorkerMessageFilter* filter, + int route_id, + int message_port_id); // Returns the single filter (must only be one). FilterInfo GetFilter() const; @@ -119,11 +127,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate, return security_policy_type_; } int worker_route_id() const { return worker_route_id_; } - int parent_process_id() const { return parent_process_id_; } int render_frame_id() const { return render_frame_id_; } - int64 main_resource_appcache_id() const { - return main_resource_appcache_id_; - } WorkerDocumentSet* worker_document_set() const { return worker_document_set_.get(); } @@ -133,6 +137,8 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate, const WorkerStoragePartition& partition() const { return partition_; } + void set_load_failed(bool failed) { load_failed_ = failed; } + bool load_failed() { return load_failed_; } private: // Set of all filters (clients) associated with this worker. @@ -142,13 +148,12 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate, base::string16 content_security_policy_; blink::WebContentSecurityPolicyType security_policy_type_; int worker_route_id_; - int parent_process_id_; int render_frame_id_; - int64 main_resource_appcache_id_; FilterList filters_; scoped_refptr<WorkerDocumentSet> worker_document_set_; ResourceContext* const resource_context_; WorkerStoragePartition partition_; + bool load_failed_; }; WorkerProcessHost(ResourceContext* resource_context, @@ -208,6 +213,9 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate, void CreateMessageFilters(int render_process_id); void OnWorkerContextClosed(int worker_route_id); + void OnWorkerScriptLoaded(int worker_route_id); + void OnWorkerScriptLoadFailed(int worker_route_id); + void OnWorkerConnected(int message_port_id, int worker_route_id); void OnAllowDatabase(int worker_route_id, const GURL& url, const base::string16& name, @@ -226,8 +234,8 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate, // Relays a message to the given endpoint. Takes care of parsing the message // if it contains a message port and sending it a valid route id. void RelayMessage(const IPC::Message& message, - WorkerMessageFilter* filter, - int route_id); + WorkerMessageFilter* incoming_filter, + WorkerInstance* instance); void ShutdownSocketStreamDispatcherHostIfNecessary(); diff --git a/content/browser/worker_host/worker_service_impl.cc b/content/browser/worker_host/worker_service_impl.cc index 84cd39c..f2ac3735 100644 --- a/content/browser/worker_host/worker_service_impl.cc +++ b/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,9 +322,7 @@ void WorkerServiceImpl::CreateWorker( params.content_security_policy, params.security_policy_type, next_worker_route_id(), - 0, params.render_frame_route_id, - params.script_resource_appcache_id, resource_context, partition); instance.AddFilter(filter, route_id); @@ -328,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) { @@ -399,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( @@ -420,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(); @@ -475,16 +376,17 @@ 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. @@ -684,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 diff --git a/content/browser/worker_host/worker_service_impl.h b/content/browser/worker_host/worker_service_impl.h index f7546eb..133c0a3 100644 --- a/content/browser/worker_host/worker_service_impl.h +++ b/content/browser/worker_host/worker_service_impl.h @@ -44,14 +44,8 @@ class CONTENT_EXPORT WorkerServiceImpl int route_id, WorkerMessageFilter* filter, ResourceContext* resource_context, - const WorkerStoragePartition& worker_partition); - void LookupSharedWorker(const ViewHostMsg_CreateWorker_Params& params, - int route_id, - WorkerMessageFilter* filter, - ResourceContext* resource_context, - const WorkerStoragePartition& worker_partition, - bool* exists, - bool* url_error); + const WorkerStoragePartition& worker_partition, + bool* url_mismatch); void ForwardToWorker(const IPC::Message& message, WorkerMessageFilter* filter); void DocumentDetached(unsigned long long document_id, @@ -105,23 +99,6 @@ class CONTENT_EXPORT WorkerServiceImpl // Tries to see if any of the queued workers can be created. void TryStartingQueuedWorker(); - // APIs for manipulating our set of pending shared worker instances. - WorkerProcessHost::WorkerInstance* CreatePendingInstance( - const GURL& url, - const base::string16& name, - ResourceContext* resource_context, - const WorkerStoragePartition& worker_partition); - WorkerProcessHost::WorkerInstance* FindPendingInstance( - const GURL& url, - const base::string16& name, - const WorkerStoragePartition& worker_partition, - ResourceContext* resource_context); - void RemovePendingInstances( - const GURL& url, - const base::string16& name, - const WorkerStoragePartition& worker_partition, - ResourceContext* resource_context); - WorkerProcessHost::WorkerInstance* FindSharedWorkerInstance( const GURL& url, const base::string16& name, @@ -134,11 +111,6 @@ class CONTENT_EXPORT WorkerServiceImpl WorkerProcessHost::Instances queued_workers_; - // These are shared workers that have been looked up, but not created yet. - // We need to keep a list of these to synchronously detect shared worker - // URL mismatches when two pages launch shared workers simultaneously. - WorkerProcessHost::Instances pending_shared_workers_; - ObserverList<WorkerServiceObserver> observers_; DISALLOW_COPY_AND_ASSIGN(WorkerServiceImpl); diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 0bfc66e..20bec60 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -342,14 +342,6 @@ IPC_STRUCT_BEGIN(ViewHostMsg_CreateWorker_Params) // RenderFrame routing id used to send messages back to the parent. IPC_STRUCT_MEMBER(int, render_frame_route_id) - - // The route ID to associate with the worker. If MSG_ROUTING_NONE is passed, - // a new unique ID is created and assigned to the worker. - IPC_STRUCT_MEMBER(int, route_id) - - // The ID of the appcache the main shared worker script resource was loaded - // from, only valid for shared workers. - IPC_STRUCT_MEMBER(int64, script_resource_appcache_id) IPC_STRUCT_END() IPC_STRUCT_BEGIN(ViewHostMsg_DateTimeDialogValue_Params) @@ -1154,10 +1146,21 @@ IPC_MESSAGE_ROUTED1(ViewMsg_DisableScrollbarsForSmallWindows, IPC_MESSAGE_ROUTED1(ViewMsg_SetActive, bool /* active */) -// Response message to ViewHostMsg_CreateShared/DedicatedWorker. +// Response message to ViewHostMsg_CreateWorker. // Sent when the worker has started. IPC_MESSAGE_ROUTED0(ViewMsg_WorkerCreated) +// Sent when the worker failed to load the worker script. +// In normal cases, this message is sent after ViewMsg_WorkerCreated is sent. +// But if the shared worker of the same URL already exists and it has failed +// to load the script, when the renderer send ViewHostMsg_CreateWorker before +// the shared worker is killed only ViewMsg_WorkerScriptLoadFailed is sent. +IPC_MESSAGE_ROUTED0(ViewMsg_WorkerScriptLoadFailed) + +// Sent when the worker has connected. +// This message is sent only if the worker successfully loaded the script. +IPC_MESSAGE_ROUTED0(ViewMsg_WorkerConnected) + // Tells the renderer that the network state has changed and that // window.navigator.onLine should be updated for all WebViews. IPC_MESSAGE_CONTROL1(ViewMsg_NetworkStateChanged, @@ -1654,21 +1657,6 @@ IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_CreateWorker, ViewHostMsg_CreateWorker_Params, int /* route_id */) -// This message is sent to the browser to see if an instance of this shared -// worker already exists. If so, it returns exists == true. If a -// non-empty name is passed, also validates that the url matches the url of -// the existing worker. If a matching worker is found, the passed-in -// document_id is associated with that worker, to ensure that the worker -// stays alive until the document is detached. -// The route_id returned can be used to forward messages to the worker via -// ForwardToWorker if it exists, otherwise it should be passed in to any -// future call to CreateWorker to avoid creating duplicate workers. -IPC_SYNC_MESSAGE_CONTROL1_3(ViewHostMsg_LookupSharedWorker, - ViewHostMsg_CreateWorker_Params, - bool /* exists */, - int /* route_id */, - bool /* url_mismatch */) - // A renderer sends this to the browser process when a document has been // detached. The browser will use this to constrain the lifecycle of worker // processes (SharedWorkers are shut down when their last associated document diff --git a/content/common/worker_messages.h b/content/common/worker_messages.h index 0507464..c562229 100644 --- a/content/common/worker_messages.h +++ b/content/common/worker_messages.h @@ -43,8 +43,6 @@ IPC_STRUCT_BEGIN(WorkerProcessMsg_CreateWorker_Params) IPC_STRUCT_MEMBER(base::string16, content_security_policy) IPC_STRUCT_MEMBER(blink::WebContentSecurityPolicyType, security_policy_type) IPC_STRUCT_MEMBER(int, route_id) - IPC_STRUCT_MEMBER(int, creator_process_id) - IPC_STRUCT_MEMBER(int64, shared_worker_appcache_id) IPC_STRUCT_END() //----------------------------------------------------------------------------- @@ -87,13 +85,6 @@ IPC_SYNC_MESSAGE_CONTROL0_0(WorkerProcessHostMsg_ForceKillWorker) //----------------------------------------------------------------------------- // Worker messages // These are messages sent from the renderer process to the worker process. -IPC_MESSAGE_ROUTED5(WorkerMsg_StartWorkerContext, - GURL /* url */, - base::string16 /* user_agent */, - base::string16 /* source_code */, - base::string16 /* content_security_policy */, - blink::WebContentSecurityPolicyType) - IPC_MESSAGE_ROUTED0(WorkerMsg_TerminateWorkerContext) IPC_MESSAGE_ROUTED2(WorkerMsg_Connect, @@ -109,4 +100,15 @@ IPC_MESSAGE_ROUTED0(WorkerMsg_WorkerObjectDestroyed) // WorkerMsg_PostMessage is also sent here. IPC_MESSAGE_CONTROL1(WorkerHostMsg_WorkerContextClosed, int /* worker_route_id */) + IPC_MESSAGE_ROUTED0(WorkerHostMsg_WorkerContextDestroyed) + +IPC_MESSAGE_CONTROL1(WorkerHostMsg_WorkerScriptLoaded, + int /* worker_route_id */) + +IPC_MESSAGE_CONTROL1(WorkerHostMsg_WorkerScriptLoadFailed, + int /* worker_route_id */) + +IPC_MESSAGE_CONTROL2(WorkerHostMsg_WorkerConnected, + int /* message_port_id */, + int /* worker_route_id */) diff --git a/content/renderer/shared_worker_repository.cc b/content/renderer/shared_worker_repository.cc index 5f4fabf70..29dacfd 100644 --- a/content/renderer/shared_worker_repository.cc +++ b/content/renderer/shared_worker_repository.cc @@ -8,6 +8,7 @@ #include "content/common/view_messages.h" #include "content/renderer/render_frame_impl.h" #include "content/renderer/websharedworker_proxy.h" +#include "third_party/WebKit/public/web/WebContentSecurityPolicy.h" #include "third_party/WebKit/public/web/WebFrame.h" namespace content { @@ -27,8 +28,6 @@ SharedWorkerRepository::createSharedWorkerConnector( const blink::WebString& content_security_policy, blink::WebContentSecurityPolicyType security_policy_type) { int route_id = MSG_ROUTING_NONE; - bool exists = false; - bool url_mismatch = false; ViewHostMsg_CreateWorker_Params params; params.url = url; params.name = name; @@ -36,16 +35,12 @@ SharedWorkerRepository::createSharedWorkerConnector( params.security_policy_type = security_policy_type; params.document_id = document_id; params.render_frame_route_id = render_frame()->GetRoutingID(); - params.route_id = MSG_ROUTING_NONE; - params.script_resource_appcache_id = 0; - Send(new ViewHostMsg_LookupSharedWorker( - params, &exists, &route_id, &url_mismatch)); - if (url_mismatch) + Send(new ViewHostMsg_CreateWorker(params, &route_id)); + if (route_id == MSG_ROUTING_NONE) return NULL; documents_with_workers_.insert(document_id); return new WebSharedWorkerProxy(ChildThread::current(), document_id, - exists, route_id, params.render_frame_route_id); } diff --git a/content/renderer/websharedworker_proxy.cc b/content/renderer/websharedworker_proxy.cc index 2da468b..840224a 100644 --- a/content/renderer/websharedworker_proxy.cc +++ b/content/renderer/websharedworker_proxy.cc @@ -15,17 +15,16 @@ namespace content { WebSharedWorkerProxy::WebSharedWorkerProxy(ChildThread* child_thread, unsigned long long document_id, - bool exists, int route_id, int render_frame_route_id) - : route_id_(exists ? route_id : MSG_ROUTING_NONE), + : route_id_(route_id), render_frame_route_id_(render_frame_route_id), child_thread_(child_thread), document_id_(document_id), pending_route_id_(route_id), - connect_listener_(NULL) { - if (route_id_ != MSG_ROUTING_NONE) - child_thread_->AddRoute(route_id_, this); + connect_listener_(NULL), + created_(false) { + child_thread_->AddRoute(route_id_, this); } WebSharedWorkerProxy::~WebSharedWorkerProxy() { @@ -48,54 +47,12 @@ void WebSharedWorkerProxy::Disconnect() { route_id_ = MSG_ROUTING_NONE; } -void WebSharedWorkerProxy::CreateWorkerContext( - const GURL& script_url, - bool is_shared, - const base::string16& name, - const base::string16& user_agent, - const base::string16& source_code, - const base::string16& content_security_policy, - blink::WebContentSecurityPolicyType policy_type, - int pending_route_id, - int64 script_resource_appcache_id) { - DCHECK(route_id_ == MSG_ROUTING_NONE); - ViewHostMsg_CreateWorker_Params params; - params.url = script_url; - params.name = name; - params.content_security_policy = content_security_policy; - params.security_policy_type = policy_type; - params.document_id = document_id_; - params.render_frame_route_id = render_frame_route_id_; - params.route_id = pending_route_id; - params.script_resource_appcache_id = script_resource_appcache_id; - IPC::Message* create_message = new ViewHostMsg_CreateWorker( - params, &route_id_); - child_thread_->Send(create_message); - if (route_id_ == MSG_ROUTING_NONE) - return; - - child_thread_->AddRoute(route_id_, this); - - // We make sure that the start message is the first, since postMessage or - // connect might have already been called. - queued_messages_.insert(queued_messages_.begin(), - new WorkerMsg_StartWorkerContext( - route_id_, script_url, user_agent, source_code, - content_security_policy, policy_type)); -} - -bool WebSharedWorkerProxy::IsStarted() { - // Worker is started if we have a route ID and there are no queued messages - // (meaning we've sent the WorkerMsg_StartWorkerContext already). - return (route_id_ != MSG_ROUTING_NONE && queued_messages_.empty()); -} - bool WebSharedWorkerProxy::Send(IPC::Message* message) { // It's possible that messages will be sent before the worker is created, in // which case route_id_ will be none. Or the worker object can be interacted // with before the browser process told us that it started, in which case we // also want to queue the message. - if (!IsStarted()) { + if (!created_) { queued_messages_.push_back(message); return true; } @@ -118,24 +75,6 @@ void WebSharedWorkerProxy::SendQueuedMessages() { } } -bool WebSharedWorkerProxy::isStarted() { - return IsStarted(); -} - -void WebSharedWorkerProxy::startWorkerContext( - const blink::WebURL& script_url, - const blink::WebString& name, - const blink::WebString& user_agent, - const blink::WebString& source_code, - const blink::WebString& content_security_policy, - blink::WebContentSecurityPolicyType policy_type, - long long script_resource_appcache_id) { - DCHECK(!isStarted()); - CreateWorkerContext( - script_url, true, name, user_agent, source_code, content_security_policy, - policy_type, pending_route_id_, script_resource_appcache_id); -} - void WebSharedWorkerProxy::connect(blink::WebMessagePortChannel* channel, ConnectListener* listener) { WebMessagePortChannelImpl* webchannel = @@ -146,32 +85,39 @@ void WebSharedWorkerProxy::connect(blink::WebMessagePortChannel* channel, webchannel->QueueMessages(); Send(new WorkerMsg_Connect(route_id_, message_port_id, MSG_ROUTING_NONE)); - if (HasQueuedMessages()) { - connect_listener_ = listener; - } else { - listener->connected(); - // The listener may free this object, so do not access the object after - // this point. - } + connect_listener_ = listener; } bool WebSharedWorkerProxy::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerProxy, message) IPC_MESSAGE_HANDLER(ViewMsg_WorkerCreated, OnWorkerCreated) + IPC_MESSAGE_HANDLER(ViewMsg_WorkerScriptLoadFailed, + OnWorkerScriptLoadFailed) + IPC_MESSAGE_HANDLER(ViewMsg_WorkerConnected, + OnWorkerConnected) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; } void WebSharedWorkerProxy::OnWorkerCreated() { - // The worker is created - now send off the CreateWorkerContext message and + created_ = true; + // The worker is created - now send off the WorkerMsg_Connect message and // any other queued messages SendQueuedMessages(); +} + +void WebSharedWorkerProxy::OnWorkerScriptLoadFailed() { + if (connect_listener_) { + // This can result in this object being freed. + connect_listener_->scriptLoadFailed(); + } +} - // Inform any listener that the pending connect event has been sent - // (this can result in this object being freed). +void WebSharedWorkerProxy::OnWorkerConnected() { if (connect_listener_) { + // This can result in this object being freed. connect_listener_->connected(); } } diff --git a/content/renderer/websharedworker_proxy.h b/content/renderer/websharedworker_proxy.h index 78a979e..b11138b 100644 --- a/content/renderer/websharedworker_proxy.h +++ b/content/renderer/websharedworker_proxy.h @@ -29,32 +29,18 @@ class WebSharedWorkerProxy : public blink::WebSharedWorkerConnector, // If the worker not loaded yet, route_id == MSG_ROUTING_NONE WebSharedWorkerProxy(ChildThread* child_thread, unsigned long long document_id, - bool exists, int route_id, int render_frame_route_id); virtual ~WebSharedWorkerProxy(); - // Implementations of WebSharedWorker APIs - virtual bool isStarted(); + // Implementations of WebSharedWorkerConnector APIs virtual void connect(blink::WebMessagePortChannel* channel, ConnectListener* listener); - virtual void startWorkerContext( - const blink::WebURL& script_url, - const blink::WebString& name, - const blink::WebString& user_agent, - const blink::WebString& source_code, - const blink::WebString& content_security_policy, - blink::WebContentSecurityPolicyType policy_type, - long long script_resource_appcache_id); - private: // IPC::Listener implementation. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - // Returns true if the worker is running (can send messages to it). - bool IsStarted(); - // Disconnects the worker (stops listening for incoming messages). void Disconnect(); @@ -68,17 +54,9 @@ class WebSharedWorkerProxy : public blink::WebSharedWorkerConnector, // Sends any messages currently in the queue. void SendQueuedMessages(); - void CreateWorkerContext(const GURL& script_url, - bool is_shared, - const base::string16& name, - const base::string16& user_agent, - const base::string16& source_code, - const base::string16& content_security_policy, - blink::WebContentSecurityPolicyType policy_type, - int pending_route_id, - int64 script_resource_appcache_id); void OnWorkerCreated(); - + void OnWorkerScriptLoadFailed(); + void OnWorkerConnected(); // Routing id associated with this worker - used to receive messages from the // worker, and also to route messages to the worker (WorkerService contains @@ -103,6 +81,7 @@ class WebSharedWorkerProxy : public blink::WebSharedWorkerConnector, // the worker). int pending_route_id_; ConnectListener* connect_listener_; + bool created_; DISALLOW_COPY_AND_ASSIGN(WebSharedWorkerProxy); }; diff --git a/content/worker/websharedworker_stub.cc b/content/worker/websharedworker_stub.cc index 5f40bab..19d3ec9 100644 --- a/content/worker/websharedworker_stub.cc +++ b/content/worker/websharedworker_stub.cc @@ -23,14 +23,11 @@ WebSharedWorkerStub::WebSharedWorkerStub( const base::string16& name, const base::string16& content_security_policy, blink::WebContentSecurityPolicyType security_policy_type, - int route_id, - const WorkerAppCacheInitInfo& appcache_init_info) + int route_id) : route_id_(route_id), - appcache_init_info_(appcache_init_info), client_(route_id, this), - name_(name), - started_(false), - worker_script_loaded_(false) { + running_(false), + url_(url) { WorkerThread* worker_thread = WorkerThread::current(); DCHECK(worker_thread); @@ -42,6 +39,8 @@ WebSharedWorkerStub::WebSharedWorkerStub( impl_ = blink::WebSharedWorker::create(client()); worker_devtools_agent_.reset(new SharedWorkerDevToolsAgent(route_id, impl_)); client()->set_devtools_agent(worker_devtools_agent_.get()); + impl_->startWorkerContext(url_, name, + content_security_policy, security_policy_type); } WebSharedWorkerStub::~WebSharedWorkerStub() { @@ -67,7 +66,6 @@ bool WebSharedWorkerStub::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerStub, message) - IPC_MESSAGE_HANDLER(WorkerMsg_StartWorkerContext, OnStartWorkerContext) IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext, OnTerminateWorkerContext) IPC_MESSAGE_HANDLER(WorkerMsg_Connect, OnConnect) @@ -84,29 +82,16 @@ const GURL& WebSharedWorkerStub::url() { return url_; } -void WebSharedWorkerStub::OnStartWorkerContext( - const GURL& url, const base::string16& user_agent, - const base::string16& source_code, - const base::string16& content_security_policy, - blink::WebContentSecurityPolicyType policy_type) { - // Ignore multiple attempts to start this worker (can happen if two pages - // try to start it simultaneously). - if (started_) - return; - - impl_->startWorkerContext(url, name_, user_agent, source_code, - content_security_policy, policy_type, 0); - started_ = true; - url_ = url; -} - void WebSharedWorkerStub::OnConnect(int sent_message_port_id, int routing_id) { - blink::WebMessagePortChannel* channel = + WebMessagePortChannelImpl* channel = new WebMessagePortChannelImpl(routing_id, sent_message_port_id, base::MessageLoopProxy::current().get()); - if (started_ && worker_script_loaded_) { + if (running_) { impl_->connect(channel); + WorkerThread::current()->Send( + new WorkerHostMsg_WorkerConnected(channel->message_port_id(), + route_id_)); } else { // If two documents try to load a SharedWorker at the same time, the // WorkerMsg_Connect for one of the documents can come in before the @@ -121,22 +106,32 @@ void WebSharedWorkerStub::OnTerminateWorkerContext() { // Call the client to make sure context exits. EnsureWorkerContextTerminates(); - started_ = false; + running_ = false; } void WebSharedWorkerStub::WorkerScriptLoaded() { - worker_script_loaded_ = true; + running_ = true; // Process any pending connections. for (PendingChannelList::const_iterator iter = pending_channels_.begin(); iter != pending_channels_.end(); ++iter) { impl_->connect(*iter); + WorkerThread::current()->Send( + new WorkerHostMsg_WorkerConnected((*iter)->message_port_id(), + route_id_)); } pending_channels_.clear(); } void WebSharedWorkerStub::WorkerScriptLoadFailed() { - // FIXME(horo): Implement this. + for (PendingChannelList::const_iterator iter = pending_channels_.begin(); + iter != pending_channels_.end(); + ++iter) { + blink::WebMessagePortChannel* channel = *iter; + channel->destroy(); + } + pending_channels_.clear(); + Shutdown(); } } // namespace content diff --git a/content/worker/websharedworker_stub.h b/content/worker/websharedworker_stub.h index bde7cba..1f9aadd 100644 --- a/content/worker/websharedworker_stub.h +++ b/content/worker/websharedworker_stub.h @@ -14,7 +14,6 @@ #include "url/gurl.h" namespace blink { -class WebMessagePortChannel; class WebSharedWorker; } @@ -31,8 +30,7 @@ class WebSharedWorkerStub : public IPC::Listener { const base::string16& name, const base::string16& content_security_policy, blink::WebContentSecurityPolicyType security_policy_type, - int route_id, - const WorkerAppCacheInitInfo& appcache_init_info); + int route_id); // IPC::Listener implementation. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; @@ -50,10 +48,6 @@ class WebSharedWorkerStub : public IPC::Listener { WebSharedWorkerClientProxy* client() { return &client_; } - const WorkerAppCacheInitInfo& appcache_init_info() const { - return appcache_init_info_; - } - // Returns the script url of this worker. const GURL& url(); @@ -62,31 +56,23 @@ class WebSharedWorkerStub : public IPC::Listener { virtual ~WebSharedWorkerStub(); void OnConnect(int sent_message_port_id, int routing_id); - void OnStartWorkerContext( - const GURL& url, const base::string16& user_agent, - const base::string16& source_code, - const base::string16& content_security_policy, - blink::WebContentSecurityPolicyType policy_type); void OnTerminateWorkerContext(); ScopedChildProcessReference process_ref_; int route_id_; - WorkerAppCacheInitInfo appcache_init_info_; // WebSharedWorkerClient that responds to outgoing API calls // from the worker object. WebSharedWorkerClientProxy client_; blink::WebSharedWorker* impl_; - base::string16 name_; - bool started_; + bool running_; GURL url_; - bool worker_script_loaded_; scoped_ptr<SharedWorkerDevToolsAgent> worker_devtools_agent_; - typedef std::vector<blink::WebMessagePortChannel*> PendingChannelList; + typedef std::vector<WebMessagePortChannelImpl*> PendingChannelList; PendingChannelList pending_channels_; DISALLOW_COPY_AND_ASSIGN(WebSharedWorkerStub); diff --git a/content/worker/websharedworkerclient_proxy.cc b/content/worker/websharedworkerclient_proxy.cc index 538657d..ade6fa6 100644 --- a/content/worker/websharedworkerclient_proxy.cc +++ b/content/worker/websharedworkerclient_proxy.cc @@ -61,11 +61,13 @@ void WebSharedWorkerClientProxy::workerContextDestroyed() { } void WebSharedWorkerClientProxy::workerScriptLoaded() { + Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_)); if (stub_) stub_->WorkerScriptLoaded(); } void WebSharedWorkerClientProxy::workerScriptLoadFailed() { + Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_)); if (stub_) stub_->WorkerScriptLoadFailed(); } @@ -91,9 +93,7 @@ WebSharedWorkerClientProxy::notificationPresenter() { WebApplicationCacheHost* WebSharedWorkerClientProxy::createApplicationCacheHost( blink::WebApplicationCacheHostClient* client) { DCHECK(!app_cache_host_); - app_cache_host_ = - new WorkerWebApplicationCacheHostImpl(stub_->appcache_init_info(), - client); + app_cache_host_ = new WorkerWebApplicationCacheHostImpl(client); // Remember the id of the instance we create so we have access to that // value when creating nested dedicated workers in createWorker. appcache_host_id_ = app_cache_host_->host_id(); diff --git a/content/worker/worker_thread.cc b/content/worker/worker_thread.cc index d19701a..8425c16 100644 --- a/content/worker/worker_thread.cc +++ b/content/worker/worker_thread.cc @@ -117,18 +117,13 @@ bool WorkerThread::OnMessageReceived(const IPC::Message& msg) { void WorkerThread::OnCreateWorker( const WorkerProcessMsg_CreateWorker_Params& params) { - WorkerAppCacheInitInfo appcache_init_info( - params.creator_process_id, - params.shared_worker_appcache_id); - // WebSharedWorkerStub own themselves. new WebSharedWorkerStub( params.url, params.name, params.content_security_policy, params.security_policy_type, - params.route_id, - appcache_init_info); + params.route_id); } // The browser process is likely dead. Terminate all workers. diff --git a/content/worker/worker_webapplicationcachehost_impl.cc b/content/worker/worker_webapplicationcachehost_impl.cc index 23201c8..b4ccb40 100644 --- a/content/worker/worker_webapplicationcachehost_impl.cc +++ b/content/worker/worker_webapplicationcachehost_impl.cc @@ -10,12 +10,9 @@ namespace content { WorkerWebApplicationCacheHostImpl::WorkerWebApplicationCacheHostImpl( - const WorkerAppCacheInitInfo& init_info, blink::WebApplicationCacheHostClient* client) : WebApplicationCacheHostImpl(client, WorkerThread::current()->appcache_dispatcher()->backend_proxy()) { - backend()->SelectCacheForSharedWorker(host_id(), - init_info.main_resource_appcache_id); } void WorkerWebApplicationCacheHostImpl::willStartMainResourceRequest( diff --git a/content/worker/worker_webapplicationcachehost_impl.h b/content/worker/worker_webapplicationcachehost_impl.h index 6f8385c..9662559 100644 --- a/content/worker/worker_webapplicationcachehost_impl.h +++ b/content/worker/worker_webapplicationcachehost_impl.h @@ -9,31 +9,13 @@ namespace content { -// Information used to construct and initialize an appcache host -// for a worker. -struct WorkerAppCacheInitInfo { - int parent_process_id; - int64 main_resource_appcache_id; // Only valid for shared workers. - - WorkerAppCacheInitInfo() - : parent_process_id(0), - main_resource_appcache_id(0) { - } - WorkerAppCacheInitInfo( - int process_id, int64 cache_id) - : parent_process_id(process_id), - main_resource_appcache_id(cache_id) { - } -}; - class WorkerWebApplicationCacheHostImpl : public WebApplicationCacheHostImpl { public: WorkerWebApplicationCacheHostImpl( - const WorkerAppCacheInitInfo& init_info, blink::WebApplicationCacheHostClient* client); - // Main resource loading is different for workers. The resource is - // loaded by the creator of the worker rather than the worker itself. + // Main resource loading is different for workers. The main resource is + // loaded by the worker using WorkerScriptLoader. // These overrides are stubbed out. virtual void willStartMainResourceRequest( blink::WebURLRequest&, const blink::WebFrame*); diff --git a/webkit/tools/layout_tests/test_expectations.txt b/webkit/tools/layout_tests/test_expectations.txt index e93f799..7415a08 100644 --- a/webkit/tools/layout_tests/test_expectations.txt +++ b/webkit/tools/layout_tests/test_expectations.txt @@ -87,3 +87,5 @@ crbug.com/330083 w3c/web-platform-tests/shadow-dom/user-interaction/focus-naviga crbug.com/330083 w3c/web-platform-tests/shadow-dom/user-interaction/focus-navigation/test-004.html [ Failure ] crbug.com/330083 w3c/web-platform-tests/shadow-dom/shadow-trees/lower-boundary-encapsulation/distribution-001.html [ ImageOnlyFailure ] crbug.com/330083 w3c/web-platform-tests/shadow-dom/shadow-trees/lower-boundary-encapsulation/distribution-002.html [ ImageOnlyFailure ] + +crbug.com/329786 http/tests/inspector/network/network-shared-worker.html [ Failure ] |