15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_job_coordinator.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/memory/scoped_ptr.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/stl_util.h"
9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "content/browser/service_worker/service_worker_register_job_base.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content {
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ServiceWorkerJobCoordinator::JobQueue::JobQueue() {}
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ServiceWorkerJobCoordinator::JobQueue::~JobQueue() {
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(jobs_.empty()) << "Destroying JobQueue with " << jobs_.size()
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        << " unfinished jobs";
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  STLDeleteElements(&jobs_);
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochServiceWorkerRegisterJobBase* ServiceWorkerJobCoordinator::JobQueue::Push(
22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    scoped_ptr<ServiceWorkerRegisterJobBase> job) {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (jobs_.empty()) {
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    job->Start();
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    jobs_.push_back(job.release());
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (!job->Equals(jobs_.back())) {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    jobs_.push_back(job.release());
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note we are releasing 'job' here.
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!jobs_.empty());
32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  return jobs_.back();
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid ServiceWorkerJobCoordinator::JobQueue::Pop(
36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    ServiceWorkerRegisterJobBase* job) {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(job == jobs_.front());
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  jobs_.pop_front();
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete job;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!jobs_.empty())
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    jobs_.front()->Start();
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ServiceWorkerJobCoordinator::JobQueue::AbortAll() {
456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  for (size_t i = 0; i < jobs_.size(); ++i)
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    jobs_[i]->Abort();
476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  STLDeleteElements(&jobs_);
486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerJobCoordinator::JobQueue::ClearForShutdown() {
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  STLDeleteElements(&jobs_);
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ServiceWorkerJobCoordinator::ServiceWorkerJobCoordinator(
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::WeakPtr<ServiceWorkerContextCore> context)
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : context_(context) {
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ServiceWorkerJobCoordinator::~ServiceWorkerJobCoordinator() {
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!context_) {
616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    for (RegistrationJobMap::iterator it = job_queues_.begin();
626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)         it != job_queues_.end(); ++it) {
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      it->second.ClearForShutdown();
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    job_queues_.clear();
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DCHECK(job_queues_.empty()) << "Destroying ServiceWorkerJobCoordinator with "
686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                              << job_queues_.size() << " job queues";
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerJobCoordinator::Register(
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& pattern,
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& script_url,
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ServiceWorkerProviderHost* provider_host,
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ServiceWorkerRegisterJob::RegistrationCallback& callback) {
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<ServiceWorkerRegisterJobBase> job(
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      new ServiceWorkerRegisterJob(context_, pattern, script_url));
78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  ServiceWorkerRegisterJob* queued_job =
796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      static_cast<ServiceWorkerRegisterJob*>(
806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          job_queues_[pattern].Push(job.Pass()));
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  queued_job->AddCallback(callback, provider_host);
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerJobCoordinator::Unregister(
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& pattern,
86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    const ServiceWorkerUnregisterJob::UnregistrationCallback& callback) {
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<ServiceWorkerRegisterJobBase> job(
88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      new ServiceWorkerUnregisterJob(context_, pattern));
89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  ServiceWorkerUnregisterJob* queued_job =
906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      static_cast<ServiceWorkerUnregisterJob*>(
916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          job_queues_[pattern].Push(job.Pass()));
92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  queued_job->AddCallback(callback);
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerJobCoordinator::Update(
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ServiceWorkerRegistration* registration) {
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(registration);
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(registration->GetNewestVersion());
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  job_queues_[registration->pattern()].Push(
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      make_scoped_ptr<ServiceWorkerRegisterJobBase>(
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          new ServiceWorkerRegisterJob(context_, registration)));
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ServiceWorkerJobCoordinator::AbortAll() {
1056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  for (RegistrationJobMap::iterator it = job_queues_.begin();
1066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)       it != job_queues_.end(); ++it) {
1076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    it->second.AbortAll();
1086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  job_queues_.clear();
1106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
1116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerJobCoordinator::FinishJob(const GURL& pattern,
113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                            ServiceWorkerRegisterJobBase* job) {
1146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  RegistrationJobMap::iterator pending_jobs = job_queues_.find(pattern);
1156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DCHECK(pending_jobs != job_queues_.end()) << "Deleting non-existent job.";
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pending_jobs->second.Pop(job);
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (pending_jobs->second.empty())
1186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    job_queues_.erase(pending_jobs);
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace content
122