Bug 1920115 - Allow high priority tasks to run before timers r=smaug
In Gecko, unlike other runnables where the TaskController picks one each at a time, the TimeoutManager allows multiple timers to run sequentially without allowing other runnables to run in between. This patch makes the user_blocking and user_visible tasks dispatched by Scheduler API can run before timers. Differential Revision: https://phabricator.services.mozilla.com/D237753
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "mozilla/net/WebSocketEventService.h"
|
||||
#include "mozilla/MediaManager.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/dom/WebTaskScheduler.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@@ -976,8 +977,12 @@ void TimeoutManager::RunTimeout(const TimeStamp& aNow,
|
||||
}
|
||||
// Check to see if we have run out of time to execute timeout handlers.
|
||||
// If we've exceeded our time budget then terminate the loop immediately.
|
||||
//
|
||||
// Or if there are high priority tasks dispatched by the Scheduler API,
|
||||
// they should run first before timers.
|
||||
TimeDuration elapsed = now - start;
|
||||
if (elapsed >= totalTimeLimit) {
|
||||
if (elapsed >= totalTimeLimit ||
|
||||
mGlobalObject.HasScheduledNormalOrHighPriorityWebTasks()) {
|
||||
// We ran out of time. Make sure to schedule the executor to
|
||||
// run immediately for the next timer, if it exists. Its possible,
|
||||
// however, that the last timeout handler suspended the window. If
|
||||
|
||||
@@ -2907,6 +2907,10 @@ bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
|
||||
return outer && outer->GetCurrentInnerWindow() == this;
|
||||
}
|
||||
|
||||
bool nsGlobalWindowInner::HasScheduledNormalOrHighPriorityWebTasks() const {
|
||||
return gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread > 0;
|
||||
}
|
||||
|
||||
bool nsPIDOMWindowInner::IsFullyActive() const {
|
||||
WindowContext* wc = GetWindowContext();
|
||||
if (!wc || wc->IsDiscarded() || !wc->IsCurrent()) {
|
||||
|
||||
@@ -338,6 +338,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
virtual bool HasActiveIndexedDBDatabases() override;
|
||||
virtual bool HasActivePeerConnections() override;
|
||||
virtual bool HasOpenWebSockets() const override;
|
||||
virtual bool HasScheduledNormalOrHighPriorityWebTasks() const override;
|
||||
void SyncStateFromParentWindow();
|
||||
|
||||
// Called on the current inner window of a browsing context when its
|
||||
|
||||
@@ -347,6 +347,10 @@ class nsIGlobalObject : public nsISupports {
|
||||
|
||||
virtual bool IsXPCSandbox() { return false; }
|
||||
|
||||
virtual bool HasScheduledNormalOrHighPriorityWebTasks() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a localized error message to the error console. Currently this
|
||||
* amounts to a wrapper around nsContentUtils::ReportToConsole for window
|
||||
|
||||
@@ -21,6 +21,14 @@ MOZ_RUNINIT static LinkedList<WebTaskScheduler> gWebTaskSchedulersMainThread;
|
||||
|
||||
static Atomic<uint64_t> gWebTaskEnqueueOrder(0);
|
||||
|
||||
// According to
|
||||
// https://github.com/WICG/scheduling-apis/issues/113#issuecomment-2596102676,
|
||||
// tasks with User_blocking or User_visible needs to run before timers.
|
||||
static bool IsNormalOrHighPriority(TaskPriority aPriority) {
|
||||
return aPriority == TaskPriority::User_blocking ||
|
||||
aPriority == TaskPriority::User_visible;
|
||||
}
|
||||
|
||||
inline void ImplCycleCollectionTraverse(
|
||||
nsCycleCollectionTraversalCallback& aCallback, WebTaskQueue& aQueue,
|
||||
const char* aName, uint32_t aFlags = 0) {
|
||||
@@ -113,6 +121,10 @@ void WebTask::RunAbortAlgorithm() {
|
||||
// was async and there's a signal.abort() call in the callback.
|
||||
if (isInList()) {
|
||||
remove();
|
||||
MOZ_ASSERT(mScheduler);
|
||||
if (HasScheduled()) {
|
||||
mScheduler->NotifyTaskWillBeRunOrAborted(this);
|
||||
}
|
||||
}
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
@@ -134,7 +146,7 @@ bool WebTask::Run() {
|
||||
MOZ_ASSERT(mScheduler);
|
||||
remove();
|
||||
|
||||
mScheduler->RemoveEntryFromTaskQueueMapIfNeeded(mWebTaskQueueHashKey);
|
||||
mScheduler->NotifyTaskWillBeRunOrAborted(this);
|
||||
ClearWebTaskScheduler();
|
||||
|
||||
if (!mCallback) {
|
||||
@@ -341,7 +353,9 @@ already_AddRefed<Promise> WebTaskScheduler::PostTask(
|
||||
|
||||
if (delay > 0) {
|
||||
nsresult rv = SetTimeoutForDelayedTask(
|
||||
task, delay, GetEventQueuePriority(finalPrioritySource->Priority()));
|
||||
task, delay,
|
||||
GetEventQueuePriority(finalPrioritySource->Priority(),
|
||||
false /* aIsContinuation */));
|
||||
if (NS_FAILED(rv)) {
|
||||
promise->MaybeRejectWithUnknownError(
|
||||
"Failed to setup timeout for delayed task");
|
||||
@@ -349,8 +363,8 @@ already_AddRefed<Promise> WebTaskScheduler::PostTask(
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (!QueueTask(task,
|
||||
GetEventQueuePriority(finalPrioritySource->Priority()))) {
|
||||
if (!DispatchTask(task, GetEventQueuePriority(finalPrioritySource->Priority(),
|
||||
false /* aIsContinuation */))) {
|
||||
MOZ_ASSERT(task->isInList());
|
||||
task->remove();
|
||||
|
||||
@@ -422,9 +436,9 @@ already_AddRefed<Promise> WebTaskScheduler::YieldImpl() {
|
||||
CreateTask(optionalSignal, {}, true /* aIsContinuation */, Nothing(),
|
||||
nullptr, promise);
|
||||
|
||||
EventQueuePriority eventQueuePriority =
|
||||
GetEventQueuePriority(prioritySource->Priority());
|
||||
if (!QueueTask(task, eventQueuePriority)) {
|
||||
EventQueuePriority eventQueuePriority = GetEventQueuePriority(
|
||||
prioritySource->Priority(), true /* aIsContinuation */);
|
||||
if (!DispatchTask(task, eventQueuePriority)) {
|
||||
MOZ_ASSERT(task->isInList());
|
||||
// CreateTask adds the task to WebTaskScheduler's queue, so we
|
||||
// need to remove from it when we failed to dispatch the runnable.
|
||||
@@ -460,12 +474,23 @@ already_AddRefed<WebTask> WebTaskScheduler::CreateTask(
|
||||
return task.forget();
|
||||
}
|
||||
|
||||
bool WebTaskScheduler::QueueTask(WebTask* aTask, EventQueuePriority aPriority) {
|
||||
bool WebTaskScheduler::DispatchTask(WebTask* aTask,
|
||||
EventQueuePriority aPriority) {
|
||||
if (!DispatchEventLoopRunnable(aPriority)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(!aTask->HasScheduled());
|
||||
aTask->SetHasScheduled(true);
|
||||
|
||||
auto taskQueue = mWebTaskQueues.Lookup(aTask->TaskQueueHashKey());
|
||||
MOZ_ASSERT(taskQueue);
|
||||
|
||||
if (IsNormalOrHighPriority(aTask->Priority()) &&
|
||||
!taskQueue->HasScheduledTasks()) {
|
||||
// This is the first task that is scheduled for this queue.
|
||||
IncreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled();
|
||||
}
|
||||
|
||||
aTask->SetHasScheduled();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -540,7 +565,24 @@ void WebTaskScheduler::Disconnect() {
|
||||
}
|
||||
|
||||
void WebTaskScheduler::RunTaskSignalPriorityChange(TaskSignal* aTaskSignal) {
|
||||
if (auto entry = mWebTaskQueues.Lookup({aTaskSignal, false})) {
|
||||
// aIsContinuation is always false because continued tasks,
|
||||
// a.k.a yield(), can't change its priority.
|
||||
WebTaskQueueHashKey key(aTaskSignal, false /* aIsContinuation */);
|
||||
if (auto entry = mWebTaskQueues.Lookup(key)) {
|
||||
if (IsNormalOrHighPriority(entry.Data().Priority()) !=
|
||||
IsNormalOrHighPriority(key.Priority())) {
|
||||
// The counter needs to be adjusted if it has scheduled tasks
|
||||
// because this queue changes its priority.
|
||||
if (entry.Data().HasScheduledTasks()) {
|
||||
if (IsNormalOrHighPriority(key.Priority())) {
|
||||
// Promoted from lower priority to high priority.
|
||||
IncreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled();
|
||||
} else {
|
||||
// Demoted from high priority to low priority.
|
||||
DecreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled();
|
||||
}
|
||||
}
|
||||
}
|
||||
entry.Data().SetPriority(aTaskSignal->Priority());
|
||||
}
|
||||
}
|
||||
@@ -575,28 +617,55 @@ WebTaskScheduler::SelectedTaskQueueData WebTaskScheduler::SelectTaskQueue(
|
||||
}
|
||||
|
||||
EventQueuePriority WebTaskScheduler::GetEventQueuePriority(
|
||||
const TaskPriority& aPriority) const {
|
||||
const TaskPriority& aPriority, bool aIsContinuation) const {
|
||||
switch (aPriority) {
|
||||
case TaskPriority::User_blocking:
|
||||
return EventQueuePriority::MediumHigh;
|
||||
case TaskPriority::User_visible:
|
||||
return aIsContinuation ? EventQueuePriority::MediumHigh
|
||||
: EventQueuePriority::Normal;
|
||||
case TaskPriority::Background:
|
||||
// Bug 1941888 intends to tweak the runnable priorities
|
||||
// for better results.
|
||||
return EventQueuePriority::Normal;
|
||||
return EventQueuePriority::Low;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid TaskPriority");
|
||||
return EventQueuePriority::Normal;
|
||||
}
|
||||
}
|
||||
|
||||
void WebTaskScheduler::RemoveEntryFromTaskQueueMapIfNeeded(
|
||||
const WebTaskQueueHashKey& aHashKey) {
|
||||
MOZ_ASSERT(mWebTaskQueues.Contains(aHashKey));
|
||||
if (auto entry = mWebTaskQueues.Lookup(aHashKey)) {
|
||||
WebTaskQueue& taskQueue = *entry;
|
||||
void WebTaskScheduler::NotifyTaskWillBeRunOrAborted(const WebTask* aWebTask) {
|
||||
const WebTaskQueueHashKey& hashKey = aWebTask->TaskQueueHashKey();
|
||||
MOZ_ASSERT(mWebTaskQueues.Contains(hashKey));
|
||||
if (auto entry = mWebTaskQueues.Lookup(hashKey)) {
|
||||
const WebTaskQueue& taskQueue = *entry;
|
||||
if (IsNormalOrHighPriority(taskQueue.Priority())) {
|
||||
// If the taskQueue
|
||||
// 1. is empty
|
||||
// 2. or it's not empty but the existing tasks are
|
||||
// not scheduled (delay tasks).
|
||||
if (!taskQueue.HasScheduledTasks()) {
|
||||
DecreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled();
|
||||
}
|
||||
}
|
||||
if (taskQueue.IsEmpty()) {
|
||||
DeleteEntryFromWebTaskQueueMap(aHashKey);
|
||||
DeleteEntryFromWebTaskQueueMap(hashKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WebTaskQueue::~WebTaskQueue() {
|
||||
MOZ_ASSERT(mScheduler);
|
||||
|
||||
bool hasScheduledTask = false;
|
||||
for (const auto& task : mTasks) {
|
||||
if (!hasScheduledTask && task->HasScheduled()) {
|
||||
hasScheduledTask = true;
|
||||
}
|
||||
task->ClearWebTaskScheduler();
|
||||
}
|
||||
mTasks.clear();
|
||||
|
||||
if (hasScheduledTask && IsNormalOrHighPriority(Priority())) {
|
||||
mScheduler->DecreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled();
|
||||
}
|
||||
}
|
||||
} // namespace mozilla::dom
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
#include "mozilla/dom/WebTaskSchedulingBinding.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
// Keep tracks of the number of same-event-loop-high-priority-queues
|
||||
// (User_blocking or User_visible) that have at least one task scheduled.
|
||||
MOZ_CONSTINIT extern uint32_t
|
||||
gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread;
|
||||
|
||||
// https://wicg.github.io/scheduling-apis/#scheduling-state
|
||||
class WebTaskSchedulingState {
|
||||
public:
|
||||
@@ -104,6 +110,16 @@ class WebTaskQueueHashKey : public PLDHashEntryHdr {
|
||||
}
|
||||
}
|
||||
|
||||
TaskPriority Priority() const {
|
||||
return mKey.match(
|
||||
[&](const StaticPriorityTaskQueueKey& aStaticKey) {
|
||||
return static_cast<TaskPriority>(aStaticKey);
|
||||
},
|
||||
[&](const DynamicPriorityTaskQueueKey& aDynamicKey) {
|
||||
return aDynamicKey->Priority();
|
||||
});
|
||||
}
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
|
||||
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey) {
|
||||
@@ -121,16 +137,6 @@ class WebTaskQueueHashKey : public PLDHashEntryHdr {
|
||||
const WebTaskQueueTypeKey& GetTypeKey() const { return mKey; }
|
||||
|
||||
private:
|
||||
TaskPriority Priority() const {
|
||||
return mKey.match(
|
||||
[&](const StaticPriorityTaskQueueKey& aStaticKey) {
|
||||
return static_cast<TaskPriority>(aStaticKey);
|
||||
},
|
||||
[&](const DynamicPriorityTaskQueueKey& aDynamicKey) {
|
||||
return aDynamicKey->Priority();
|
||||
});
|
||||
}
|
||||
|
||||
WebTaskQueueTypeKey mKey;
|
||||
const bool mIsContinuation;
|
||||
};
|
||||
@@ -160,8 +166,17 @@ class WebTask : public LinkedListElement<RefPtr<WebTask>>,
|
||||
|
||||
void ClearWebTaskScheduler() { mScheduler = nullptr; }
|
||||
|
||||
const WebTaskQueueHashKey& TaskQueueHashKey() const {
|
||||
return mWebTaskQueueHashKey;
|
||||
}
|
||||
|
||||
TaskPriority Priority() const { return mWebTaskQueueHashKey.Priority(); }
|
||||
|
||||
private:
|
||||
void SetHasScheduled(bool aHasScheduled) { mHasScheduled = aHasScheduled; }
|
||||
void SetHasScheduled() {
|
||||
MOZ_ASSERT(!mHasScheduled);
|
||||
mHasScheduled = true;
|
||||
}
|
||||
|
||||
uint32_t mEnqueueOrder;
|
||||
|
||||
@@ -188,18 +203,13 @@ class WebTaskQueue {
|
||||
public:
|
||||
static constexpr int EffectivePriorityCount = 6;
|
||||
|
||||
explicit WebTaskQueue(WebTaskScheduler* aScheduler) {
|
||||
explicit WebTaskQueue(WebTaskScheduler* aScheduler) : mScheduler(aScheduler) {
|
||||
MOZ_ASSERT(aScheduler);
|
||||
}
|
||||
|
||||
WebTaskQueue(WebTaskQueue&& aWebTaskQueue) = default;
|
||||
|
||||
~WebTaskQueue() {
|
||||
for (const auto& task : mTasks) {
|
||||
task->ClearWebTaskScheduler();
|
||||
}
|
||||
mTasks.clear();
|
||||
}
|
||||
~WebTaskQueue();
|
||||
|
||||
TaskPriority Priority() const { return mPriority; }
|
||||
void SetPriority(TaskPriority aNewPriority) { mPriority = aNewPriority; }
|
||||
@@ -238,6 +248,10 @@ class WebTaskQueue {
|
||||
private:
|
||||
TaskPriority mPriority = TaskPriority::User_visible;
|
||||
LinkedList<RefPtr<WebTask>> mTasks;
|
||||
|
||||
// WebTaskScheduler owns WebTaskQueue as a hashtable value, so using a raw
|
||||
// pointer points to WebTaskScheduler is ok.
|
||||
WebTaskScheduler* mScheduler;
|
||||
};
|
||||
|
||||
class WebTaskSchedulerMainThread;
|
||||
@@ -281,7 +295,9 @@ class WebTaskScheduler : public nsWrapperCache,
|
||||
MOZ_ASSERT(result);
|
||||
}
|
||||
|
||||
void RemoveEntryFromTaskQueueMapIfNeeded(const WebTaskQueueHashKey&);
|
||||
void NotifyTaskWillBeRunOrAborted(const WebTask* aWebTask);
|
||||
virtual void IncreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() = 0;
|
||||
virtual void DecreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~WebTaskScheduler() = default;
|
||||
@@ -299,7 +315,7 @@ class WebTaskScheduler : public nsWrapperCache,
|
||||
const Maybe<SchedulerPostTaskCallback&>& aCallback,
|
||||
WebTaskSchedulingState* aSchedulingState, Promise* aPromise);
|
||||
|
||||
bool QueueTask(WebTask* aTask, EventQueuePriority aPriority);
|
||||
bool DispatchTask(WebTask* aTask, EventQueuePriority aPriority);
|
||||
|
||||
SelectedTaskQueueData SelectTaskQueue(
|
||||
const Optional<OwningNonNull<AbortSignal>>& aSignal,
|
||||
@@ -309,7 +325,8 @@ class WebTaskScheduler : public nsWrapperCache,
|
||||
EventQueuePriority aPriority) = 0;
|
||||
virtual bool DispatchEventLoopRunnable(EventQueuePriority aPriority) = 0;
|
||||
|
||||
EventQueuePriority GetEventQueuePriority(const TaskPriority& aPriority) const;
|
||||
EventQueuePriority GetEventQueuePriority(const TaskPriority& aPriority,
|
||||
bool aIsContinuation) const;
|
||||
|
||||
nsTHashMap<WebTaskQueueHashKey, WebTaskQueue>& GetWebTaskQueues() {
|
||||
return mWebTaskQueues;
|
||||
@@ -330,7 +347,7 @@ class DelayedWebTaskHandler final : public TimeoutHandler {
|
||||
MOZ_CAN_RUN_SCRIPT bool Call(const char* /* unused */) override {
|
||||
if (mScheduler && mWebTask) {
|
||||
MOZ_ASSERT(!mWebTask->HasScheduled());
|
||||
if (!mScheduler->QueueTask(mWebTask, mPriority)) {
|
||||
if (!mScheduler->DispatchTask(mWebTask, mPriority)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
uint32_t gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread = 0;
|
||||
|
||||
NS_IMETHODIMP WebTaskMainThreadRunnable::Run() {
|
||||
if (mScheduler) {
|
||||
RefPtr<WebTask> task = mScheduler->GetNextTask(true /* aIsMainThread */);
|
||||
@@ -52,4 +54,16 @@ bool WebTaskSchedulerMainThread::DispatchEventLoopRunnable(
|
||||
NS_DispatchToMainThreadQueue(runnable.forget(), aPriority));
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebTaskSchedulerMainThread::
|
||||
IncreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() {
|
||||
++gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread;
|
||||
}
|
||||
|
||||
void WebTaskSchedulerMainThread::
|
||||
DecreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread > 0);
|
||||
--gNumNormalOrHighPriorityQueuesHaveTaskScheduledMainThread;
|
||||
}
|
||||
} // namespace mozilla::dom
|
||||
|
||||
@@ -32,6 +32,9 @@ class WebTaskSchedulerMainThread final : public WebTaskScheduler {
|
||||
explicit WebTaskSchedulerMainThread(nsIGlobalObject* aParent)
|
||||
: WebTaskScheduler(aParent) {}
|
||||
|
||||
void IncreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() override;
|
||||
void DecreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() override;
|
||||
|
||||
private:
|
||||
nsresult SetTimeoutForDelayedTask(WebTask* aTask, uint64_t aDelay,
|
||||
EventQueuePriority aPriority) override;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "mozilla/dom/TimeoutManager.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
WebTaskWorkerRunnable::WebTaskWorkerRunnable(
|
||||
WebTaskSchedulerWorker* aSchedulerWorker)
|
||||
: WorkerSameThreadRunnable("WebTaskWorkerRunnable"),
|
||||
@@ -113,4 +112,16 @@ void WebTaskSchedulerWorker::Disconnect() {
|
||||
}
|
||||
WebTaskScheduler::Disconnect();
|
||||
}
|
||||
|
||||
void WebTaskSchedulerWorker::
|
||||
IncreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() {
|
||||
++mNumHighPriorityQueuesHaveTaskScheduled;
|
||||
}
|
||||
|
||||
void WebTaskSchedulerWorker::
|
||||
DecreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() {
|
||||
MOZ_ASSERT(mNumHighPriorityQueuesHaveTaskScheduled > 0);
|
||||
--mNumHighPriorityQueuesHaveTaskScheduled;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
@@ -38,6 +38,13 @@ class WebTaskSchedulerWorker final : public WebTaskScheduler {
|
||||
|
||||
void Disconnect() override;
|
||||
|
||||
void IncreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() override;
|
||||
void DecreaseNumNormalOrHighPriorityQueuesHaveTaskScheduled() override;
|
||||
|
||||
bool HasScheduledNormalOrHighPriorityWebTasks() const {
|
||||
return mNumHighPriorityQueuesHaveTaskScheduled;
|
||||
}
|
||||
|
||||
private:
|
||||
~WebTaskSchedulerWorker() = default;
|
||||
|
||||
@@ -47,6 +54,12 @@ class WebTaskSchedulerWorker final : public WebTaskScheduler {
|
||||
|
||||
RefPtr<StrongWorkerRef> mWorkerRef;
|
||||
bool mWorkerIsShuttingDown{false};
|
||||
|
||||
// Unlike window global where multiple globals can share the
|
||||
// same event loop, worker globals don't share event loops,
|
||||
// so it's okay to have this counter lives inside the
|
||||
// scheduler for workers.
|
||||
uint32_t mNumHighPriorityQueuesHaveTaskScheduled = 0;
|
||||
};
|
||||
} // namespace mozilla::dom
|
||||
#endif
|
||||
|
||||
@@ -771,6 +771,13 @@ int32_t WorkerGlobalScope::SetTimeoutOrInterval(
|
||||
Timeout::Reason::eTimeoutOrInterval, aRv);
|
||||
}
|
||||
|
||||
bool WorkerGlobalScope::HasScheduledNormalOrHighPriorityWebTasks() const {
|
||||
if (!mWebTaskScheduler) {
|
||||
return false;
|
||||
}
|
||||
return mWebTaskScheduler->HasScheduledNormalOrHighPriorityWebTasks();
|
||||
}
|
||||
|
||||
void WorkerGlobalScope::GetOrigin(nsAString& aOrigin) const {
|
||||
AssertIsOnWorkerThread();
|
||||
nsContentUtils::GetWebExposedOriginSerialization(
|
||||
|
||||
@@ -387,6 +387,7 @@ class WorkerGlobalScope : public WorkerGlobalScopeBase {
|
||||
WebTaskScheduler* Scheduler();
|
||||
WebTaskScheduler* GetExistingScheduler() const;
|
||||
void SetWebTaskSchedulingState(WebTaskSchedulingState* aState) override;
|
||||
bool HasScheduledNormalOrHighPriorityWebTasks() const override;
|
||||
|
||||
WebTaskSchedulingState* GetWebTaskSchedulingState() const override {
|
||||
return mWebTaskSchedulingState;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
[yield-priority-timers.any.worker.html]
|
||||
[yield() with timer tasks (inherit signal)]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[yield-priority-timers.any.html]
|
||||
[yield() with timer tasks (inherit signal)]
|
||||
expected: FAIL
|
||||
Reference in New Issue
Block a user