Bug 1731274 [wpt PR 30792] - Add WebIDL.idl as a dependency for webtransport idlharne...
[gecko.git] / dom / serviceworkers / ServiceWorkerJobQueue.cpp
blobdb7b2748a1254282ac3a963709dbe457f8e3432d
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/. */
7 #include "ServiceWorkerJobQueue.h"
9 #include "nsThreadUtils.h"
10 #include "ServiceWorkerJob.h"
11 #include "mozilla/dom/WorkerCommon.h"
13 namespace mozilla {
14 namespace dom {
16 class ServiceWorkerJobQueue::Callback final
17 : public ServiceWorkerJob::Callback {
18 RefPtr<ServiceWorkerJobQueue> mQueue;
20 ~Callback() = default;
22 public:
23 explicit Callback(ServiceWorkerJobQueue* aQueue) : mQueue(aQueue) {
24 MOZ_ASSERT(NS_IsMainThread());
25 MOZ_ASSERT(mQueue);
28 virtual void JobFinished(ServiceWorkerJob* aJob,
29 ErrorResult& aStatus) override {
30 MOZ_ASSERT(NS_IsMainThread());
31 mQueue->JobFinished(aJob);
34 virtual void JobDiscarded(ErrorResult&) override {
35 // no-op; nothing to do.
38 NS_INLINE_DECL_REFCOUNTING(ServiceWorkerJobQueue::Callback, override)
41 ServiceWorkerJobQueue::~ServiceWorkerJobQueue() {
42 MOZ_ASSERT(NS_IsMainThread());
43 MOZ_ASSERT(mJobList.IsEmpty());
46 void ServiceWorkerJobQueue::JobFinished(ServiceWorkerJob* aJob) {
47 MOZ_ASSERT(NS_IsMainThread());
48 MOZ_ASSERT(aJob);
50 // XXX There are some corner cases where jobs can double-complete. Until
51 // we track all these down we do a non-fatal assert in debug builds and
52 // a runtime check to verify the queue is in the correct state.
53 NS_ASSERTION(!mJobList.IsEmpty(),
54 "Job queue should contain the job that just completed.");
55 NS_ASSERTION(mJobList.SafeElementAt(0, nullptr) == aJob,
56 "Job queue should contain the job that just completed.");
57 if (NS_WARN_IF(mJobList.SafeElementAt(0, nullptr) != aJob)) {
58 return;
61 mJobList.RemoveElementAt(0);
63 if (mJobList.IsEmpty()) {
64 return;
67 RunJob();
70 void ServiceWorkerJobQueue::RunJob() {
71 MOZ_ASSERT(NS_IsMainThread());
72 MOZ_ASSERT(!mJobList.IsEmpty());
73 MOZ_ASSERT(mJobList[0]->GetState() == ServiceWorkerJob::State::Initial);
75 RefPtr<Callback> callback = new Callback(this);
76 mJobList[0]->Start(callback);
79 ServiceWorkerJobQueue::ServiceWorkerJobQueue() {
80 MOZ_ASSERT(NS_IsMainThread());
83 void ServiceWorkerJobQueue::ScheduleJob(ServiceWorkerJob* aJob) {
84 MOZ_ASSERT(NS_IsMainThread());
85 MOZ_ASSERT(aJob);
86 MOZ_ASSERT(!mJobList.Contains(aJob));
88 if (mJobList.IsEmpty()) {
89 mJobList.AppendElement(aJob);
90 RunJob();
91 return;
94 MOZ_ASSERT(mJobList[0]->GetState() == ServiceWorkerJob::State::Started);
96 RefPtr<ServiceWorkerJob>& tailJob = mJobList[mJobList.Length() - 1];
97 if (!tailJob->ResultCallbacksInvoked() && aJob->IsEquivalentTo(tailJob)) {
98 tailJob->StealResultCallbacksFrom(aJob);
99 return;
102 mJobList.AppendElement(aJob);
105 void ServiceWorkerJobQueue::CancelAll() {
106 MOZ_ASSERT(NS_IsMainThread());
108 for (RefPtr<ServiceWorkerJob>& job : mJobList) {
109 job->Cancel();
112 // Remove jobs that are queued but not started since they should never
113 // run after being canceled. This means throwing away all jobs except
114 // for the job at the front of the list.
115 if (!mJobList.IsEmpty()) {
116 MOZ_ASSERT(mJobList[0]->GetState() == ServiceWorkerJob::State::Started);
117 mJobList.TruncateLength(1);
121 } // namespace dom
122 } // namespace mozilla