Bug 1626278: Implement MozPromise::AllSettled, based on JS Promise API. r=jya

Differential Revision: https://phabricator.services.mozilla.com/D91467
This commit is contained in:
Byron Campen [:bwc] 2020-11-19 18:50:08 +00:00
Родитель 9599563a0c
Коммит e0c988cd55
1 изменённых файлов: 67 добавлений и 0 удалений

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

@ -291,6 +291,9 @@ class MozPromise : public MozPromiseBase {
IsExclusive>
AllPromiseType;
typedef MozPromise<CopyableTArray<ResolveOrRejectValue>, bool, IsExclusive>
AllSettledPromiseType;
private:
class AllPromiseHolder : public MozPromiseRefcountable {
public:
@ -340,6 +343,50 @@ class MozPromise : public MozPromiseBase {
size_t mOutstandingPromises;
};
// Trying to pass ResolveOrRejectValue by value fails static analysis checks,
// so we need to use either a const& or an rvalue reference, depending on
// whether IsExclusive is true or not.
typedef std::conditional_t<IsExclusive, ResolveOrRejectValue&&,
const ResolveOrRejectValue&>
ResolveOrRejectValueParam;
class AllSettledPromiseHolder : public MozPromiseRefcountable {
public:
explicit AllSettledPromiseHolder(size_t aDependentPromises)
: mPromise(new typename AllSettledPromiseType::Private(__func__)),
mOutstandingPromises(aDependentPromises) {
MOZ_ASSERT(aDependentPromises > 0);
mValues.SetLength(aDependentPromises);
}
void Settle(size_t aIndex, ResolveOrRejectValueParam aValue) {
if (!mPromise) {
// Already rejected.
return;
}
mValues[aIndex].emplace(MaybeMove(aValue));
if (--mOutstandingPromises == 0) {
nsTArray<ResolveOrRejectValue> values;
values.SetCapacity(mValues.Length());
for (auto&& value : mValues) {
values.AppendElement(std::move(value.ref()));
}
mPromise->Resolve(std::move(values), __func__);
mPromise = nullptr;
mValues.Clear();
}
}
AllSettledPromiseType* Promise() { return mPromise; }
private:
nsTArray<Maybe<ResolveOrRejectValue>> mValues;
RefPtr<typename AllSettledPromiseType::Private> mPromise;
size_t mOutstandingPromises;
};
public:
[[nodiscard]] static RefPtr<AllPromiseType> All(
nsISerialEventTarget* aProcessingTarget,
@ -364,6 +411,26 @@ class MozPromise : public MozPromiseBase {
return promise;
}
[[nodiscard]] static RefPtr<AllSettledPromiseType> AllSettled(
nsISerialEventTarget* aProcessingTarget,
nsTArray<RefPtr<MozPromise>>& aPromises) {
if (aPromises.Length() == 0) {
return AllSettledPromiseType::CreateAndResolve(
CopyableTArray<ResolveOrRejectValue>(), __func__);
}
RefPtr<AllSettledPromiseHolder> holder =
new AllSettledPromiseHolder(aPromises.Length());
RefPtr<AllSettledPromiseType> promise = holder->Promise();
for (size_t i = 0; i < aPromises.Length(); ++i) {
aPromises[i]->Then(aProcessingTarget, __func__,
[holder, i](ResolveOrRejectValueParam aValue) -> void {
holder->Settle(i, MaybeMove(aValue));
});
}
return promise;
}
class Request : public MozPromiseRefcountable {
public:
virtual void Disconnect() = 0;