• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/browser/service_worker/service_worker_job_coordinator.h"
6 
7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util.h"
9 #include "content/browser/service_worker/service_worker_register_job_base.h"
10 
11 namespace content {
12 
JobQueue()13 ServiceWorkerJobCoordinator::JobQueue::JobQueue() {}
14 
~JobQueue()15 ServiceWorkerJobCoordinator::JobQueue::~JobQueue() {
16   DCHECK(jobs_.empty()) << "Destroying JobQueue with " << jobs_.size()
17                         << " unfinished jobs";
18   STLDeleteElements(&jobs_);
19 }
20 
Push(scoped_ptr<ServiceWorkerRegisterJobBase> job)21 ServiceWorkerRegisterJobBase* ServiceWorkerJobCoordinator::JobQueue::Push(
22     scoped_ptr<ServiceWorkerRegisterJobBase> job) {
23   if (jobs_.empty()) {
24     job->Start();
25     jobs_.push_back(job.release());
26   } else if (!job->Equals(jobs_.back())) {
27     jobs_.push_back(job.release());
28   }
29   // Note we are releasing 'job' here.
30 
31   DCHECK(!jobs_.empty());
32   return jobs_.back();
33 }
34 
Pop(ServiceWorkerRegisterJobBase * job)35 void ServiceWorkerJobCoordinator::JobQueue::Pop(
36     ServiceWorkerRegisterJobBase* job) {
37   DCHECK(job == jobs_.front());
38   jobs_.pop_front();
39   delete job;
40   if (!jobs_.empty())
41     jobs_.front()->Start();
42 }
43 
AbortAll()44 void ServiceWorkerJobCoordinator::JobQueue::AbortAll() {
45   for (size_t i = 0; i < jobs_.size(); ++i)
46     jobs_[i]->Abort();
47   STLDeleteElements(&jobs_);
48 }
49 
ClearForShutdown()50 void ServiceWorkerJobCoordinator::JobQueue::ClearForShutdown() {
51   STLDeleteElements(&jobs_);
52 }
53 
ServiceWorkerJobCoordinator(base::WeakPtr<ServiceWorkerContextCore> context)54 ServiceWorkerJobCoordinator::ServiceWorkerJobCoordinator(
55     base::WeakPtr<ServiceWorkerContextCore> context)
56     : context_(context) {
57 }
58 
~ServiceWorkerJobCoordinator()59 ServiceWorkerJobCoordinator::~ServiceWorkerJobCoordinator() {
60   if (!context_) {
61     for (RegistrationJobMap::iterator it = job_queues_.begin();
62          it != job_queues_.end(); ++it) {
63       it->second.ClearForShutdown();
64     }
65     job_queues_.clear();
66   }
67   DCHECK(job_queues_.empty()) << "Destroying ServiceWorkerJobCoordinator with "
68                               << job_queues_.size() << " job queues";
69 }
70 
Register(const GURL & pattern,const GURL & script_url,ServiceWorkerProviderHost * provider_host,const ServiceWorkerRegisterJob::RegistrationCallback & callback)71 void ServiceWorkerJobCoordinator::Register(
72     const GURL& pattern,
73     const GURL& script_url,
74     ServiceWorkerProviderHost* provider_host,
75     const ServiceWorkerRegisterJob::RegistrationCallback& callback) {
76   scoped_ptr<ServiceWorkerRegisterJobBase> job(
77       new ServiceWorkerRegisterJob(context_, pattern, script_url));
78   ServiceWorkerRegisterJob* queued_job =
79       static_cast<ServiceWorkerRegisterJob*>(
80           job_queues_[pattern].Push(job.Pass()));
81   queued_job->AddCallback(callback, provider_host);
82 }
83 
Unregister(const GURL & pattern,const ServiceWorkerUnregisterJob::UnregistrationCallback & callback)84 void ServiceWorkerJobCoordinator::Unregister(
85     const GURL& pattern,
86     const ServiceWorkerUnregisterJob::UnregistrationCallback& callback) {
87   scoped_ptr<ServiceWorkerRegisterJobBase> job(
88       new ServiceWorkerUnregisterJob(context_, pattern));
89   ServiceWorkerUnregisterJob* queued_job =
90       static_cast<ServiceWorkerUnregisterJob*>(
91           job_queues_[pattern].Push(job.Pass()));
92   queued_job->AddCallback(callback);
93 }
94 
Update(ServiceWorkerRegistration * registration)95 void ServiceWorkerJobCoordinator::Update(
96     ServiceWorkerRegistration* registration) {
97   DCHECK(registration);
98   DCHECK(registration->GetNewestVersion());
99   job_queues_[registration->pattern()].Push(
100       make_scoped_ptr<ServiceWorkerRegisterJobBase>(
101           new ServiceWorkerRegisterJob(context_, registration)));
102 }
103 
AbortAll()104 void ServiceWorkerJobCoordinator::AbortAll() {
105   for (RegistrationJobMap::iterator it = job_queues_.begin();
106        it != job_queues_.end(); ++it) {
107     it->second.AbortAll();
108   }
109   job_queues_.clear();
110 }
111 
FinishJob(const GURL & pattern,ServiceWorkerRegisterJobBase * job)112 void ServiceWorkerJobCoordinator::FinishJob(const GURL& pattern,
113                                             ServiceWorkerRegisterJobBase* job) {
114   RegistrationJobMap::iterator pending_jobs = job_queues_.find(pattern);
115   DCHECK(pending_jobs != job_queues_.end()) << "Deleting non-existent job.";
116   pending_jobs->second.Pop(job);
117   if (pending_jobs->second.empty())
118     job_queues_.erase(pending_jobs);
119 }
120 
121 }  // namespace content
122