tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ServiceWorkerJobQueue.cpp (3437B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "ServiceWorkerJobQueue.h"
      8 
      9 #include "ServiceWorkerJob.h"
     10 #include "mozilla/dom/WorkerCommon.h"
     11 #include "nsThreadUtils.h"
     12 
     13 namespace mozilla::dom {
     14 
     15 class ServiceWorkerJobQueue::Callback final
     16    : public ServiceWorkerJob::Callback {
     17  RefPtr<ServiceWorkerJobQueue> mQueue;
     18 
     19  ~Callback() = default;
     20 
     21 public:
     22  explicit Callback(ServiceWorkerJobQueue* aQueue) : mQueue(aQueue) {
     23    MOZ_ASSERT(NS_IsMainThread());
     24    MOZ_ASSERT(mQueue);
     25  }
     26 
     27  virtual void JobFinished(ServiceWorkerJob* aJob,
     28                           ErrorResult& aStatus) override {
     29    MOZ_ASSERT(NS_IsMainThread());
     30    mQueue->JobFinished(aJob);
     31  }
     32 
     33  virtual void JobDiscarded(ErrorResult&) override {
     34    // no-op; nothing to do.
     35  }
     36 
     37  NS_INLINE_DECL_REFCOUNTING(ServiceWorkerJobQueue::Callback, override)
     38 };
     39 
     40 ServiceWorkerJobQueue::~ServiceWorkerJobQueue() {
     41  MOZ_ASSERT(NS_IsMainThread());
     42  MOZ_ASSERT(mJobList.IsEmpty());
     43 }
     44 
     45 void ServiceWorkerJobQueue::JobFinished(ServiceWorkerJob* aJob) {
     46  MOZ_ASSERT(NS_IsMainThread());
     47  MOZ_ASSERT(aJob);
     48 
     49  // XXX There are some corner cases where jobs can double-complete.  Until
     50  // we track all these down we do a non-fatal assert in debug builds and
     51  // a runtime check to verify the queue is in the correct state.
     52  NS_ASSERTION(!mJobList.IsEmpty(),
     53               "Job queue should contain the job that just completed.");
     54  NS_ASSERTION(mJobList.SafeElementAt(0, nullptr) == aJob,
     55               "Job queue should contain the job that just completed.");
     56  if (NS_WARN_IF(mJobList.SafeElementAt(0, nullptr) != aJob)) {
     57    return;
     58  }
     59 
     60  mJobList.RemoveElementAt(0);
     61 
     62  if (mJobList.IsEmpty()) {
     63    return;
     64  }
     65 
     66  RunJob();
     67 }
     68 
     69 void ServiceWorkerJobQueue::RunJob() {
     70  MOZ_ASSERT(NS_IsMainThread());
     71  MOZ_ASSERT(!mJobList.IsEmpty());
     72  MOZ_ASSERT(mJobList[0]->GetState() == ServiceWorkerJob::State::Initial);
     73 
     74  RefPtr<Callback> callback = new Callback(this);
     75  mJobList[0]->Start(callback);
     76 }
     77 
     78 ServiceWorkerJobQueue::ServiceWorkerJobQueue() {
     79  MOZ_ASSERT(NS_IsMainThread());
     80 }
     81 
     82 void ServiceWorkerJobQueue::ScheduleJob(ServiceWorkerJob* aJob) {
     83  MOZ_ASSERT(NS_IsMainThread());
     84  MOZ_ASSERT(aJob);
     85  MOZ_ASSERT(!mJobList.Contains(aJob));
     86 
     87  if (mJobList.IsEmpty()) {
     88    mJobList.AppendElement(aJob);
     89    RunJob();
     90    return;
     91  }
     92 
     93  MOZ_ASSERT(mJobList[0]->GetState() == ServiceWorkerJob::State::Started);
     94 
     95  RefPtr<ServiceWorkerJob>& tailJob = mJobList[mJobList.Length() - 1];
     96  if (!tailJob->ResultCallbacksInvoked() && aJob->IsEquivalentTo(tailJob)) {
     97    tailJob->StealResultCallbacksFrom(aJob);
     98    return;
     99  }
    100 
    101  mJobList.AppendElement(aJob);
    102 }
    103 
    104 void ServiceWorkerJobQueue::CancelAll() {
    105  MOZ_ASSERT(NS_IsMainThread());
    106 
    107  for (RefPtr<ServiceWorkerJob>& job : mJobList) {
    108    job->Cancel();
    109  }
    110 
    111  // Remove jobs that are queued but not started since they should never
    112  // run after being canceled.  This means throwing away all jobs except
    113  // for the job at the front of the list.
    114  if (!mJobList.IsEmpty()) {
    115    MOZ_ASSERT(mJobList[0]->GetState() == ServiceWorkerJob::State::Started);
    116    mJobList.TruncateLength(1);
    117  }
    118 }
    119 
    120 }  // namespace mozilla::dom