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

Unified Diff: content/browser/worker_host/worker_service_impl.cc

Issue 22314003: NavigationController prototype Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: NavController prototype - chrome side Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/worker_host/worker_service_impl.h ('k') | content/child/appcache/appcache_backend_proxy.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/worker_host/worker_service_impl.cc
diff --git a/content/browser/worker_host/worker_service_impl.cc b/content/browser/worker_host/worker_service_impl.cc
index 5fb8e62bedb9f328f75e452f8455c52ebdd3a8e5..cd618f3ae7a64902b5d668385e17f88e97785bc3 100644
--- a/content/browser/worker_host/worker_service_impl.cc
+++ b/content/browser/worker_host/worker_service_impl.cc
@@ -393,85 +393,150 @@ void WorkerServiceImpl::DocumentDetached(unsigned long long document_id,
}
}
-bool WorkerServiceImpl::CreateWorkerFromInstance(
- WorkerProcessHost::WorkerInstance instance) {
- if (!CanCreateWorkerProcess(instance)) {
- queued_workers_.push_back(instance);
- return true;
- }
+int WorkerServiceImpl::CreateAndStartEmbeddedWorker(
+ ResourceContext* resource_context,
+ const WorkerStoragePartition& partition,
+ const GURL& url,
+ const std::string& raw_handler_source,
+ int64 associated_appcache_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // 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.
+ int worker_route_id = next_worker_route_id();
+ WorkerProcessHost::WorkerInstance instance(
+ url,
+ string16(),
+ worker_route_id,
+ 0,
+ 0, // associated_appcache_id,
+ resource_context,
+ partition);
+ instance.is_embedded_worker_ = true;
+ CreateWorkerFromInstance(instance);
+ SendToEmbeddedWorker(
+ worker_route_id,
+ new WorkerMsg_StartEmbeddedWorkerContext(
+ worker_route_id, url, raw_handler_source));
+ return worker_route_id;
+}
- // 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;
+namespace {
+// Helper to get the WPH for a given embedded worker id.
+WorkerProcessHost* FindEmbeddedWorkerProcessHost(int worker_route_id) {
+ for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
+ const WorkerProcessHost::Instances& instances = (*iter)->instances();
+ for (WorkerProcessHost::Instances::const_iterator i = instances.begin();
+ i != instances.end(); ++i) {
+ if (i->is_embedded_worker_ && i->worker_route_id() == worker_route_id) {
+ return *iter;
+ }
+ }
}
+ return NULL;
+}
+} // namespace
- // 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";
+bool WorkerServiceImpl::SendToEmbeddedWorker(
+ int worker_route_id, IPC::Message* message) {
+ WorkerProcessHost* host = FindEmbeddedWorkerProcessHost(worker_route_id);
+ if (!host) {
+ delete message;
return false;
}
+ return host->Send(message);
+}
- // 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());
+void WorkerServiceImpl::TerminateEmbeddedWorker(int worker_route_id) {
+ WorkerProcessHost* host = FindEmbeddedWorkerProcessHost(worker_route_id);
+ if (!host)
+ return;
+ host->TerminateWorker(worker_route_id);
+}
- // 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.partition(), instance.resource_context())) {
- 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;
+bool WorkerServiceImpl::CreateWorkerFromInstance(
+ WorkerProcessHost::WorkerInstance instance) {
+ if (!instance.is_embedded_worker_) {
+ if (!CanCreateWorkerProcess(instance)) {
+ queued_workers_.push_back(instance);
+ 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();
+ iter != queued_workers_.end();) {
+ if (iter->Matches(instance.url(), instance.name(),
+ instance.partition(), instance.resource_context())) {
+ 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;
+ }
}
+ DCHECK_EQ(instance.filters().begin()->first->render_process_id(),
+ instance.parent_process_id());
}
- WorkerMessageFilter* first_filter = instance.filters().begin()->first;
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(instance.parent_process_id())) {
delete worker;
return false;
}
@@ -568,6 +633,7 @@ bool WorkerServiceImpl::GetRendererForWorker(int worker_process_id,
continue;
// This code assumes one worker per process, see function comment in header!
+ // ^^^ gee, lovely ^^^
WorkerProcessHost::Instances::const_iterator first_instance =
iter->instances().begin();
if (first_instance == iter->instances().end())
« no previous file with comments | « content/browser/worker_host/worker_service_impl.h ('k') | content/child/appcache/appcache_backend_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698