From 25fc505c3e0122d58c1202ede01fc55694c609ae Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 8 Dec 2014 17:19:05 -0800 Subject: [PATCH] Bug 1108767 - Add the ability to chain same-type promises. r=cpearce --- dom/media/MediaPromise.h | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/dom/media/MediaPromise.h b/dom/media/MediaPromise.h index 5450630fe94..16a7058646e 100644 --- a/dom/media/MediaPromise.h +++ b/dom/media/MediaPromise.h @@ -225,6 +225,19 @@ public: } } + void ChainTo(already_AddRefed aChainedPromise, const char* aCallSite) + { + MutexAutoLock lock(mMutex); + nsRefPtr 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) { MutexAutoLock lock(mMutex); @@ -251,6 +264,21 @@ protected: for (size_t i = 0; i < mThenValues.Length(); ++i) mThenValues[i]->Dispatch(this); 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(), ""); + } else { + aOther->Reject(mRejectValue.ref(), ""); + } } ~MediaPromise() @@ -258,6 +286,8 @@ protected: MOZ_COUNT_DTOR(MediaPromise); PROMISE_LOG("MediaPromise::~MediaPromise [this=%p]", this); MOZ_ASSERT(!IsPending()); + MOZ_ASSERT(mThenValues.IsEmpty()); + MOZ_ASSERT(mChainedPromises.IsEmpty()); }; const char* mCreationSite; // For logging @@ -265,6 +295,7 @@ protected: Maybe mResolveValue; Maybe mRejectValue; nsTArray mThenValues; + nsTArray> mChainedPromises; }; /* @@ -302,6 +333,17 @@ public: return !mPromise; } + already_AddRefed Steal() + { + if (mMonitor) { + mMonitor->AssertCurrentThreadOwns(); + } + + nsRefPtr p = mPromise; + mPromise = nullptr; + return p.forget(); + } + void Resolve(typename PromiseType::ResolveValueType aResolveValue, const char* aMethodName) {