Bug 1800347, make it possible to set the priority of the Runnables used by MozPromise, r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D161954
This commit is contained in:
Olli Pettay 2022-11-16 09:23:28 +00:00
parent bc632c1a55
commit 0372c2251a
3 changed files with 56 additions and 3 deletions

View File

@ -466,10 +466,12 @@ class MozPromise : public MozPromiseBase {
static const uint32_t sMagic = 0xfadece11;
public:
class ResolveOrRejectRunnable : public CancelableRunnable {
class ResolveOrRejectRunnable final
: public PrioritizableCancelableRunnable {
public:
ResolveOrRejectRunnable(ThenValueBase* aThenValue, MozPromise* aPromise)
: CancelableRunnable(
: PrioritizableCancelableRunnable(
aPromise->mPriority,
"MozPromise::ThenValueBase::ResolveOrRejectRunnable"),
mThenValue(aThenValue),
mPromise(aPromise) {
@ -1071,6 +1073,8 @@ class MozPromise : public MozPromiseBase {
if (mUseSynchronousTaskDispatch) {
chainedPromise->UseSynchronousTaskDispatch(aCallSite);
}
} else {
chainedPromise->SetTaskPriority(mPriority, aCallSite);
}
if (!IsPending()) {
@ -1176,6 +1180,7 @@ class MozPromise : public MozPromiseBase {
ResolveOrRejectValue mValue;
bool mUseSynchronousTaskDispatch = false;
bool mUseDirectTaskDispatch = false;
uint32_t mPriority = nsIRunnablePriority::PRIORITY_NORMAL;
# ifdef PROMISE_DEBUG
uint32_t mMagic1 = sMagic;
# endif
@ -1293,6 +1298,25 @@ class MozPromise<ResolveValueT, RejectValueT, IsExclusive>::Private
"Promise already set for synchronous dispatch");
mUseDirectTaskDispatch = true;
}
// If the resolve/reject will be handled on a thread supporting priorities,
// one may want to tweak the priority of the task by passing a
// nsIRunnablePriority::PRIORITY_* to SetTaskPriority.
void SetTaskPriority(uint32_t aPriority, const char* aSite) {
PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic &&
mMagic3 == sMagic && mMagic4 == &mMutex);
MutexAutoLock lock(mMutex);
PROMISE_LOG("%s TaskPriority MozPromise (%p created at %s)", aSite, this,
mCreationSite);
MOZ_ASSERT(IsPending(),
"A Promise must not have been already resolved or rejected to "
"set dispatch state");
MOZ_ASSERT(!mUseSynchronousTaskDispatch,
"Promise already set for synchronous dispatch");
MOZ_ASSERT(!mUseDirectTaskDispatch,
"Promise already set for direct dispatch");
mPriority = aPriority;
}
};
// A generic promise type that does the trick for simple use cases.
@ -1408,6 +1432,11 @@ class MozPromiseHolderBase {
mPromise->UseDirectTaskDispatch(aSite);
}
void SetTaskPriority(uint32_t aPriority, const char* aSite) {
MOZ_ASSERT(mPromise);
mPromise->SetTaskPriority(aPriority, aSite);
}
private:
RefPtr<typename PromiseType::Private> mPromise;
};

View File

@ -143,6 +143,15 @@ already_AddRefed<nsIRunnable> mozilla::CreateRenderBlockingRunnable(
return runnable.forget();
}
NS_IMPL_ISUPPORTS_INHERITED(PrioritizableCancelableRunnable, CancelableRunnable,
nsIRunnablePriority)
NS_IMETHODIMP
PrioritizableCancelableRunnable::GetPriority(uint32_t* aPriority) {
*aPriority = mPriority;
return NS_OK;
}
#endif // XPCOM_GLUE_AVOID_NSPR
//-----------------------------------------------------------------------------

View File

@ -505,11 +505,26 @@ class PrioritizableRunnable : public Runnable, public nsIRunnablePriority {
protected:
virtual ~PrioritizableRunnable() = default;
;
nsCOMPtr<nsIRunnable> mRunnable;
uint32_t mPriority;
};
class PrioritizableCancelableRunnable : public CancelableRunnable,
public nsIRunnablePriority {
public:
PrioritizableCancelableRunnable(uint32_t aPriority, const char* aName)
: CancelableRunnable(aName), mPriority(aPriority) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIRUNNABLEPRIORITY
protected:
virtual ~PrioritizableCancelableRunnable() = default;
const uint32_t mPriority;
};
extern already_AddRefed<nsIRunnable> CreateRenderBlockingRunnable(
already_AddRefed<nsIRunnable>&& aRunnable);