Bug 1169542 - Implement MediaPromise::All. r=jww

This commit is contained in:
Bobby Holley 2015-05-28 16:04:40 -07:00
parent 5f7ed91c80
commit ea959672b1
2 changed files with 106 additions and 0 deletions

View File

@ -206,6 +206,67 @@ public:
return Move(p);
}
typedef MediaPromise<nsTArray<ResolveValueType>, RejectValueType, IsExclusive> AllPromiseType;
private:
class AllPromiseHolder : public MediaPromiseRefcountable
{
public:
explicit AllPromiseHolder(size_t aDependentPromises)
: mPromise(new typename AllPromiseType::Private(__func__))
, mOutstandingPromises(aDependentPromises)
{
mResolveValues.SetLength(aDependentPromises);
}
void Resolve(size_t aIndex, const ResolveValueType& aResolveValue)
{
if (!mPromise) {
// Already rejected.
return;
}
mResolveValues[aIndex].emplace(aResolveValue);
if (--mOutstandingPromises == 0) {
nsTArray<ResolveValueType> resolveValues;
resolveValues.SetCapacity(mResolveValues.Length());
for (size_t i = 0; i < mResolveValues.Length(); ++i) {
resolveValues.AppendElement(mResolveValues[i].ref());
}
mPromise->Resolve(resolveValues, __func__);
mPromise = nullptr;
mResolveValues.Clear();
}
}
void Reject(const RejectValueType& aRejectValue)
{
mPromise->Reject(aRejectValue, __func__);
mPromise = nullptr;
mResolveValues.Clear();
}
AllPromiseType* Promise() { return mPromise; }
private:
nsTArray<Maybe<ResolveValueType>> mResolveValues;
nsRefPtr<typename AllPromiseType::Private> mPromise;
size_t mOutstandingPromises;
};
public:
static nsRefPtr<AllPromiseType> All(AbstractThread* aProcessingThread, nsTArray<nsRefPtr<MediaPromise>>& aPromises)
{
nsRefPtr<AllPromiseHolder> holder = new AllPromiseHolder(aPromises.Length());
for (size_t i = 0; i < aPromises.Length(); ++i) {
aPromises[i]->Then(aProcessingThread, __func__,
[holder, i] (ResolveValueType aResolveValue) -> void { holder->Resolve(i, aResolveValue); },
[holder] (RejectValueType aRejectValue) -> void { holder->Reject(aRejectValue); }
);
}
return holder->Promise();
}
class Request : public MediaPromiseRefcountable
{
public:

View File

@ -173,4 +173,49 @@ TEST(MediaPromise, CompletionPromises)
});
}
TEST(MediaPromise, PromiseAllResolve)
{
AutoTaskQueue atq;
nsRefPtr<MediaTaskQueue> queue = atq.TaskQueue();
RunOnTaskQueue(queue, [queue] () -> void {
nsTArray<nsRefPtr<TestPromise>> promises;
promises.AppendElement(TestPromise::CreateAndResolve(22, __func__));
promises.AppendElement(TestPromise::CreateAndResolve(32, __func__));
promises.AppendElement(TestPromise::CreateAndResolve(42, __func__));
TestPromise::All(queue, promises)->Then(queue, __func__,
[queue] (const nsTArray<int>& aResolveValues) -> void {
EXPECT_EQ(aResolveValues.Length(), 3UL);
EXPECT_EQ(aResolveValues[0], 22);
EXPECT_EQ(aResolveValues[1], 32);
EXPECT_EQ(aResolveValues[2], 42);
queue->BeginShutdown();
},
DO_FAIL
);
});
}
TEST(MediaPromise, PromiseAllReject)
{
AutoTaskQueue atq;
nsRefPtr<MediaTaskQueue> queue = atq.TaskQueue();
RunOnTaskQueue(queue, [queue] () -> void {
nsTArray<nsRefPtr<TestPromise>> promises;
promises.AppendElement(TestPromise::CreateAndResolve(22, __func__));
promises.AppendElement(TestPromise::CreateAndReject(32.0, __func__));
promises.AppendElement(TestPromise::CreateAndResolve(42, __func__));
TestPromise::All(queue, promises)->Then(queue, __func__,
DO_FAIL,
[queue] (float aRejectValue) -> void {
EXPECT_EQ(aRejectValue, 32.0);
queue->BeginShutdown();
}
);
});
}
#undef DO_FAIL