TaskSignal.cpp (3472B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:expandtab:shiftwidth=2:tabstop=2: 3 */ 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #include "TaskSignal.h" 9 10 #include "WebTaskScheduler.h" 11 12 namespace mozilla::dom { 13 14 NS_IMPL_CYCLE_COLLECTION_INHERITED(TaskSignal, AbortSignal, 15 mDependentTaskSignals) 16 17 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(TaskSignal, AbortSignal) 18 19 already_AddRefed<TaskSignal> TaskSignal::Create(nsIGlobalObject* aGlobalObject, 20 TaskPriority aPriority) { 21 return do_AddRef(new TaskSignal(aGlobalObject, aPriority)); 22 } 23 24 void TaskSignal::RunPriorityChangeAlgorithms() { 25 for (const WeakPtr<WebTaskScheduler>& scheduler : mSchedulers) { 26 if (scheduler) { 27 scheduler->RunTaskSignalPriorityChange(this); 28 } 29 } 30 } 31 void TaskSignal::SetWebTaskScheduler(WebTaskScheduler* aScheduler) { 32 mSchedulers.AppendElement(aScheduler); 33 } 34 35 // https://wicg.github.io/scheduling-apis/#create-a-dependent-task-signal 36 /* static */ 37 already_AddRefed<TaskSignal> TaskSignal::Any( 38 GlobalObject& aGlobal, const Sequence<OwningNonNull<AbortSignal>>& aSignals, 39 const TaskSignalAnyInit& aInit) { 40 nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports()); 41 // 1. Let resultSignal be the result of creating a dependent signal from 42 // signals using the TaskSignal interface and realm. 43 RefPtr<AbortSignal> abortSignal = 44 AbortSignal::Any(global, aSignals, [](nsIGlobalObject* aGlobal) { 45 // Use User_visible as a temporary priority for now, it'll alwasy be set 46 // again later. 47 RefPtr<TaskSignal> signal = 48 new TaskSignal(aGlobal, TaskPriority::User_visible); 49 return signal.forget(); 50 }); 51 52 if (!abortSignal) { 53 return nullptr; 54 } 55 56 RefPtr<TaskSignal> resultSignal = static_cast<TaskSignal*>(abortSignal.get()); 57 58 // 2. Set resultSignal’s dependent to true. 59 resultSignal->mDependent = true; 60 61 // 3. If init["priority"] is a TaskPriority, then: 62 if (aInit.mPriority.IsTaskPriority()) { 63 // 3.1 Set resultSignal’s priority to init["priority"]. 64 resultSignal->SetPriority(aInit.mPriority.GetAsTaskPriority()); 65 return resultSignal.forget(); 66 } 67 68 // 4. Otherwise: 69 // 4.1. Let sourceSignal be init["priority"]. 70 OwningNonNull<TaskSignal> sourceSignal = aInit.mPriority.GetAsTaskSignal(); 71 72 // 4.2. Set resultSignal’s priority to sourceSignal’s priority. 73 resultSignal->SetPriority(sourceSignal->Priority()); 74 75 // 4.3 If sourceSignal does not have fixed priority, then: 76 if (!sourceSignal->HasFixedPriority()) { 77 // 4.3.1 If sourceSignal’s dependent is true, then set sourceSignal to 78 // sourceSignal’s source signal 79 if (sourceSignal->mDependent) { 80 sourceSignal = sourceSignal->mSourceTaskSignal; 81 } 82 // 4.3.2. Assert: sourceSignal is not dependent. 83 MOZ_ASSERT(!sourceSignal->mDependent); 84 // 4.3.3. Set resultSignal’s source signal to a weak reference to 85 // sourceSignal. 86 resultSignal->mSourceTaskSignal = sourceSignal; 87 // 4.3.4. Append resultSignal to sourceSignal’s dependent signals. 88 sourceSignal->mDependentTaskSignals.AppendElement(resultSignal); 89 } 90 return resultSignal.forget(); 91 } 92 } // namespace mozilla::dom