summaryrefslogtreecommitdiffstats
path: root/chrome/browser/worker_host/worker_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/worker_host/worker_service.cc')
-rw-r--r--chrome/browser/worker_host/worker_service.cc64
1 files changed, 48 insertions, 16 deletions
diff --git a/chrome/browser/worker_host/worker_service.cc b/chrome/browser/worker_host/worker_service.cc
index fe768c3..ffdbb1d 100644
--- a/chrome/browser/worker_host/worker_service.cc
+++ b/chrome/browser/worker_host/worker_service.cc
@@ -49,6 +49,7 @@ 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,
@@ -61,10 +62,10 @@ bool WorkerService::CreateWorker(const GURL &url,
is_shared,
off_the_record,
name,
- renderer_id,
- render_view_route_id,
next_worker_route_id());
instance.AddSender(sender, sender_route_id);
+ instance.worker_document_set()->Add(
+ sender, document_id, renderer_id, render_view_route_id);
WorkerProcessHost* worker = NULL;
if (CommandLine::ForCurrentProcess()->HasSwitch(
@@ -89,6 +90,7 @@ bool WorkerService::CreateWorker(const GURL &url,
// 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) {
+ // TODO(atwilson): Change this to scan the sender list (crbug.com/29243).
existing_instance->AddSender(sender, sender_route_id);
sender->Send(new ViewMsg_WorkerCreated(sender_route_id));
return true;
@@ -108,8 +110,8 @@ bool WorkerService::CreateWorker(const GURL &url,
// Assign the accumulated document set and sender list for this pending
// worker to the new instance.
- DCHECK(!pending->IsDocumentSetEmpty());
- instance.CopyDocumentSet(*pending);
+ DCHECK(!pending->worker_document_set()->IsEmpty());
+ instance.ShareDocumentSet(*pending);
RemovePendingInstance(url, name, off_the_record);
}
@@ -129,6 +131,8 @@ 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) {
@@ -160,7 +164,8 @@ bool WorkerService::LookupSharedWorker(const GURL &url,
instance->AddSender(sender, sender_route_id);
// Add the passed sender/document_id to the worker instance.
- instance->AddToDocumentSet(sender, document_id);
+ instance->worker_document_set()->Add(
+ sender, document_id, renderer_id, render_view_route_id);
return found_instance;
}
@@ -176,8 +181,8 @@ void WorkerService::DocumentDetached(IPC::Message::Sender* sender,
for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin();
iter != queued_workers_.end();) {
if (iter->shared()) {
- iter->RemoveFromDocumentSet(sender, document_id);
- if (iter->IsDocumentSetEmpty()) {
+ iter->worker_document_set()->Remove(sender, document_id);
+ if (iter->worker_document_set()->IsEmpty()) {
iter = queued_workers_.erase(iter);
continue;
}
@@ -189,8 +194,8 @@ void WorkerService::DocumentDetached(IPC::Message::Sender* sender,
for (WorkerProcessHost::Instances::iterator iter =
pending_shared_workers_.begin();
iter != pending_shared_workers_.end(); ) {
- iter->RemoveFromDocumentSet(sender, document_id);
- if (iter->IsDocumentSetEmpty()) {
+ iter->worker_document_set()->Remove(sender, document_id);
+ if (iter->worker_document_set()->IsEmpty()) {
iter = pending_shared_workers_.erase(iter);
} else {
++iter;
@@ -294,8 +299,35 @@ WorkerProcessHost* WorkerService::GetLeastLoadedWorker() {
bool WorkerService::CanCreateWorkerProcess(
const WorkerProcessHost::WorkerInstance& instance) {
+ // Worker can be fired off if *any* parent has room.
+ const WorkerDocumentSet::DocumentInfoSet& parents =
+ instance.worker_document_set()->documents();
+
+ for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter =
+ 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(),
+ &hit_total_worker_limit)) {
+ return true;
+ }
+ // Return false if already at the global worker limit (no need to continue
+ // checking parent tabs).
+ if (hit_total_worker_limit)
+ return false;
+ }
+ // If we've reached here, none of the parent tabs is allowed to create an
+ // instance.
+ return false;
+}
+
+bool WorkerService::TabCanCreateWorkerProcess(int renderer_id,
+ int render_view_route_id,
+ bool* hit_total_worker_limit) {
int total_workers = 0;
int workers_per_tab = 0;
+ *hit_total_worker_limit = false;
for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
!iter.Done(); ++iter) {
WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
@@ -303,11 +335,11 @@ bool WorkerService::CanCreateWorkerProcess(
worker->instances().begin();
cur_instance != worker->instances().end(); ++cur_instance) {
total_workers++;
- if (total_workers >= kMaxWorkersWhenSeparate)
+ if (total_workers >= kMaxWorkersWhenSeparate) {
+ *hit_total_worker_limit = true;
return false;
- if (cur_instance->renderer_id() == instance.renderer_id() &&
- cur_instance->render_view_route_id() ==
- instance.render_view_route_id()) {
+ }
+ if (cur_instance->RendererIsParent(renderer_id, render_view_route_id)) {
workers_per_tab++;
if (workers_per_tab >= kMaxWorkersPerTabWhenSeparate)
return false;
@@ -355,8 +387,8 @@ void WorkerService::SenderShutdown(IPC::Message::Sender* sender) {
for (WorkerProcessHost::Instances::iterator iter =
pending_shared_workers_.begin();
iter != pending_shared_workers_.end(); ) {
- iter->RemoveAllAssociatedDocuments(sender);
- if (iter->IsDocumentSetEmpty()) {
+ iter->worker_document_set()->RemoveAll(sender);
+ if (iter->worker_document_set()->IsEmpty()) {
iter = pending_shared_workers_.erase(iter);
} else {
++iter;
@@ -461,7 +493,7 @@ WorkerService::CreatePendingInstance(const GURL& url,
// No existing pending worker - create a new one.
WorkerProcessHost::WorkerInstance pending(
- url, true, off_the_record, name, 0, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
+ url, true, off_the_record, name, MSG_ROUTING_NONE);
pending_shared_workers_.push_back(pending);
return &pending_shared_workers_.back();
}