Bug 1792203 - Immediately resolve AsyncBlockers when no blocker are registered r=nika

Differential Revision: https://phabricator.services.mozilla.com/D158028
This commit is contained in:
Alexandre Lissy 2022-10-25 07:31:46 +00:00
Родитель 5956c400ec
Коммит b8bc940e27
2 изменённых файлов: 27 добавлений и 26 удалений

Просмотреть файл

@ -29,32 +29,21 @@ class AsyncBlockers {
mPromise(new GenericPromise::Private(__func__)) {}
void Register(void* aBlocker) {
MutexAutoLock lock(mLock);
if (mResolved) {
// Too late.
return;
}
mBlockers.InsertElementSorted(aBlocker);
}
void Deregister(void* aBlocker) {
MutexAutoLock lock(mLock);
if (mResolved) {
// Too late.
return;
}
MOZ_ASSERT(mBlockers.ContainsSorted(aBlocker));
MOZ_ALWAYS_TRUE(mBlockers.RemoveElementSorted(aBlocker));
MaybeResolve();
}
RefPtr<GenericPromise> WaitUntilClear(uint32_t aTimeOutInMs = 0) {
if (!aTimeOutInMs) {
// We don't need to wait, resolve the promise right away.
{
MutexAutoLock lock(mLock);
if (!mResolved) {
mPromise->Resolve(true, __func__);
mResolved = true;
}
} else {
MaybeResolve();
}
if (aTimeOutInMs > 0) {
GetCurrentEventTarget()->DelayedDispatch(
NS_NewRunnableFunction("AsyncBlockers::WaitUntilClear",
[promise = mPromise]() {
@ -69,30 +58,22 @@ class AsyncBlockers {
}),
aTimeOutInMs);
}
return mPromise;
}
virtual ~AsyncBlockers() {
if (!mResolved) {
mPromise->Resolve(true, __func__);
}
}
virtual ~AsyncBlockers() { mPromise->Resolve(true, __func__); }
private:
void MaybeResolve() MOZ_REQUIRES(mLock) {
mLock.AssertCurrentThreadOwns();
if (mResolved) {
return;
}
if (!mBlockers.IsEmpty()) {
return;
}
mPromise->Resolve(true, __func__);
mResolved = true;
}
Mutex mLock;
nsTArray<void*> mBlockers MOZ_GUARDED_BY(mLock);
bool mResolved MOZ_GUARDED_BY(mLock) = false;
const RefPtr<GenericPromise::Private> mPromise;
};

Просмотреть файл

@ -136,6 +136,26 @@ TEST_F(TestAsyncBlockers, NoRegister_WaitUntilClear) {
PROCESS_EVENTS_UNTIL(done);
}
TEST_F(TestAsyncBlockers, Register_WaitUntilClear_0s) {
AsyncBlockers blockers;
bool done = false;
Blocker* blocker = new Blocker();
blockers.Register(blocker);
blockers.WaitUntilClear(0)->Then(GetCurrentSerialEventTarget(), __func__,
[&]() {
EXPECT_TRUE(true);
done = true;
});
NS_ProcessPendingEvents(nullptr);
blockers.Deregister(blocker);
PROCESS_EVENTS_UNTIL(done);
}
#if !defined(ANDROID)
static void DisableCrashReporter() {
nsCOMPtr<nsICrashReporter> crashreporter =