Bug 1108767 - Add the ability to chain same-type promises. r=cpearce

This commit is contained in:
Bobby Holley 2014-12-08 17:19:05 -08:00
parent 5827f5f41e
commit 25fc505c3e

View File

@ -225,6 +225,19 @@ public:
} }
} }
void ChainTo(already_AddRefed<MediaPromise> aChainedPromise, const char* aCallSite)
{
MutexAutoLock lock(mMutex);
nsRefPtr<MediaPromise> chainedPromise = aChainedPromise;
PROMISE_LOG("%s invoking Chain() [this=%p, chainedPromise=%p, isPending=%d]",
aCallSite, this, chainedPromise.get(), (int) IsPending());
if (!IsPending()) {
ForwardTo(chainedPromise);
} else {
mChainedPromises.AppendElement(chainedPromise);
}
}
void Resolve(ResolveValueType aResolveValue, const char* aResolveSite) void Resolve(ResolveValueType aResolveValue, const char* aResolveSite)
{ {
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
@ -251,6 +264,21 @@ protected:
for (size_t i = 0; i < mThenValues.Length(); ++i) for (size_t i = 0; i < mThenValues.Length(); ++i)
mThenValues[i]->Dispatch(this); mThenValues[i]->Dispatch(this);
mThenValues.Clear(); mThenValues.Clear();
for (size_t i = 0; i < mChainedPromises.Length(); ++i) {
ForwardTo(mChainedPromises[i]);
}
mChainedPromises.Clear();
}
void ForwardTo(MediaPromise* aOther)
{
MOZ_ASSERT(!IsPending());
if (mResolveValue.isSome()) {
aOther->Resolve(mResolveValue.ref(), "<chained promise>");
} else {
aOther->Reject(mRejectValue.ref(), "<chained promise>");
}
} }
~MediaPromise() ~MediaPromise()
@ -258,6 +286,8 @@ protected:
MOZ_COUNT_DTOR(MediaPromise); MOZ_COUNT_DTOR(MediaPromise);
PROMISE_LOG("MediaPromise::~MediaPromise [this=%p]", this); PROMISE_LOG("MediaPromise::~MediaPromise [this=%p]", this);
MOZ_ASSERT(!IsPending()); MOZ_ASSERT(!IsPending());
MOZ_ASSERT(mThenValues.IsEmpty());
MOZ_ASSERT(mChainedPromises.IsEmpty());
}; };
const char* mCreationSite; // For logging const char* mCreationSite; // For logging
@ -265,6 +295,7 @@ protected:
Maybe<ResolveValueType> mResolveValue; Maybe<ResolveValueType> mResolveValue;
Maybe<RejectValueType> mRejectValue; Maybe<RejectValueType> mRejectValue;
nsTArray<ThenValueBase*> mThenValues; nsTArray<ThenValueBase*> mThenValues;
nsTArray<nsRefPtr<MediaPromise>> mChainedPromises;
}; };
/* /*
@ -302,6 +333,17 @@ public:
return !mPromise; return !mPromise;
} }
already_AddRefed<PromiseType> Steal()
{
if (mMonitor) {
mMonitor->AssertCurrentThreadOwns();
}
nsRefPtr<PromiseType> p = mPromise;
mPromise = nullptr;
return p.forget();
}
void Resolve(typename PromiseType::ResolveValueType aResolveValue, void Resolve(typename PromiseType::ResolveValueType aResolveValue,
const char* aMethodName) const char* aMethodName)
{ {