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.
5 #include "content/browser/service_worker/service_worker_job_coordinator.h"
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"
13 ServiceWorkerJobCoordinator::JobQueue::JobQueue() {}
15 ServiceWorkerJobCoordinator::JobQueue::~JobQueue() {
16 DCHECK(jobs_.empty()) << "Destroying JobQueue with " << jobs_.size()
17 << " unfinished jobs";
18 STLDeleteElements(&jobs_);
21 ServiceWorkerRegisterJobBase* ServiceWorkerJobCoordinator::JobQueue::Push(
22 scoped_ptr<ServiceWorkerRegisterJobBase> job) {
25 jobs_.push_back(job.release());
26 } else if (!job->Equals(jobs_.back())) {
27 jobs_.push_back(job.release());
29 // Note we are releasing 'job' here.
31 DCHECK(!jobs_.empty());
35 void ServiceWorkerJobCoordinator::JobQueue::Pop(
36 ServiceWorkerRegisterJobBase* job) {
37 DCHECK(job == jobs_.front());
41 jobs_.front()->Start();
44 void ServiceWorkerJobCoordinator::JobQueue::AbortAll() {
45 for (size_t i = 0; i < jobs_.size(); ++i)
47 STLDeleteElements(&jobs_);
50 void ServiceWorkerJobCoordinator::JobQueue::ClearForShutdown() {
51 STLDeleteElements(&jobs_);
54 ServiceWorkerJobCoordinator::ServiceWorkerJobCoordinator(
55 base::WeakPtr<ServiceWorkerContextCore> context)
59 ServiceWorkerJobCoordinator::~ServiceWorkerJobCoordinator() {
61 for (RegistrationJobMap::iterator it = job_queues_.begin();
62 it != job_queues_.end(); ++it) {
63 it->second.ClearForShutdown();
67 DCHECK(job_queues_.empty()) << "Destroying ServiceWorkerJobCoordinator with "
68 << job_queues_.size() << " job queues";
71 void ServiceWorkerJobCoordinator::Register(
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);
84 void ServiceWorkerJobCoordinator::Unregister(
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);
95 void ServiceWorkerJobCoordinator::Update(
96 ServiceWorkerRegistration* registration) {
98 DCHECK(registration->GetNewestVersion());
99 job_queues_[registration->pattern()].Push(
100 make_scoped_ptr<ServiceWorkerRegisterJobBase>(
101 new ServiceWorkerRegisterJob(context_, registration)));
104 void ServiceWorkerJobCoordinator::AbortAll() {
105 for (RegistrationJobMap::iterator it = job_queues_.begin();
106 it != job_queues_.end(); ++it) {
107 it->second.AbortAll();
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);
121 } // namespace content