Home | History | Annotate | Download | only in service_worker
      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 
     13 ServiceWorkerJobCoordinator::JobQueue::JobQueue() {}
     14 
     15 ServiceWorkerJobCoordinator::JobQueue::~JobQueue() {
     16   DCHECK(jobs_.empty()) << "Destroying JobQueue with " << jobs_.size()
     17                         << " unfinished jobs";
     18   STLDeleteElements(&jobs_);
     19 }
     20 
     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 
     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 
     44 void ServiceWorkerJobCoordinator::JobQueue::AbortAll() {
     45   for (size_t i = 0; i < jobs_.size(); ++i)
     46     jobs_[i]->Abort();
     47   STLDeleteElements(&jobs_);
     48 }
     49 
     50 void ServiceWorkerJobCoordinator::JobQueue::ClearForShutdown() {
     51   STLDeleteElements(&jobs_);
     52 }
     53 
     54 ServiceWorkerJobCoordinator::ServiceWorkerJobCoordinator(
     55     base::WeakPtr<ServiceWorkerContextCore> context)
     56     : context_(context) {
     57 }
     58 
     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 
     71 void ServiceWorkerJobCoordinator::Register(
     72     const GURL& pattern,
     73     const GURL& script_url,
     74     int source_process_id,
     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, source_process_id);
     82 }
     83 
     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 
     95 void ServiceWorkerJobCoordinator::AbortAll() {
     96   for (RegistrationJobMap::iterator it = job_queues_.begin();
     97        it != job_queues_.end(); ++it) {
     98     it->second.AbortAll();
     99   }
    100   job_queues_.clear();
    101 }
    102 
    103 void ServiceWorkerJobCoordinator::FinishJob(const GURL& pattern,
    104                                             ServiceWorkerRegisterJobBase* job) {
    105   RegistrationJobMap::iterator pending_jobs = job_queues_.find(pattern);
    106   DCHECK(pending_jobs != job_queues_.end()) << "Deleting non-existent job.";
    107   pending_jobs->second.Pop(job);
    108   if (pending_jobs->second.empty())
    109     job_queues_.erase(pending_jobs);
    110 }
    111 
    112 }  // namespace content
    113