mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 1123983 - Implement exclusivity checking for MediaPromises. r=cpearce
This commit is contained in:
parent
5a43979bbc
commit
a18cc7d480
@ -50,10 +50,15 @@ public:
|
||||
CANCELED
|
||||
};
|
||||
|
||||
typedef MediaPromise<nsRefPtr<AudioData>, NotDecodedReason> AudioDataPromise;
|
||||
typedef MediaPromise<nsRefPtr<VideoData>, NotDecodedReason> VideoDataPromise;
|
||||
typedef MediaPromise<int64_t, nsresult> SeekPromise;
|
||||
typedef MediaPromise<MediaData::Type, WaitForDataRejectValue> WaitForDataPromise;
|
||||
typedef MediaPromise<nsRefPtr<AudioData>, NotDecodedReason, /* IsExclusive = */ true> AudioDataPromise;
|
||||
typedef MediaPromise<nsRefPtr<VideoData>, NotDecodedReason, /* IsExclusive = */ true> VideoDataPromise;
|
||||
typedef MediaPromise<int64_t, nsresult, /* IsExclusive = */ true> SeekPromise;
|
||||
|
||||
// Note that, conceptually, WaitForData makes sense in a non-exclusive sense.
|
||||
// But in the current architecture it's only ever used exclusively (by MDSM),
|
||||
// so we mark it that way to verify our assumptions. If you have a use-case
|
||||
// for multiple WaitForData consumers, feel free to flip the exclusivity here.
|
||||
typedef MediaPromise<MediaData::Type, WaitForDataRejectValue, /* IsExclusive = */ true> WaitForDataPromise;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
|
||||
|
||||
|
@ -45,11 +45,11 @@ nsresult DispatchMediaPromiseRunnable(nsIEventTarget* aTarget, nsIRunnable* aRun
|
||||
* callbacks to be invoked (asynchronously, on a specified thread) when the
|
||||
* request is either completed (resolved) or cannot be completed (rejected).
|
||||
*
|
||||
* By default, resolve and reject callbacks are always invoked on the same thread
|
||||
* where Then() was invoked.
|
||||
* When IsExclusive is true, the MediaPromise does a release-mode assertion that
|
||||
* there is at most one call to either Then(...) or ChainTo(...).
|
||||
*/
|
||||
template<typename T> class MediaPromiseHolder;
|
||||
template<typename ResolveValueT, typename RejectValueT>
|
||||
template<typename ResolveValueT, typename RejectValueT, bool IsExclusive>
|
||||
class MediaPromise
|
||||
{
|
||||
public:
|
||||
@ -60,24 +60,23 @@ public:
|
||||
explicit MediaPromise(const char* aCreationSite)
|
||||
: mCreationSite(aCreationSite)
|
||||
, mMutex("MediaPromise Mutex")
|
||||
, mHaveConsumer(false)
|
||||
{
|
||||
PROMISE_LOG("%s creating MediaPromise (%p)", mCreationSite, this);
|
||||
}
|
||||
|
||||
static nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>>
|
||||
static nsRefPtr<MediaPromise>
|
||||
CreateAndResolve(ResolveValueType aResolveValue, const char* aResolveSite)
|
||||
{
|
||||
nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>> p =
|
||||
new MediaPromise<ResolveValueT, RejectValueT>(aResolveSite);
|
||||
nsRefPtr<MediaPromise> p = new MediaPromise(aResolveSite);
|
||||
p->Resolve(aResolveValue, aResolveSite);
|
||||
return p;
|
||||
}
|
||||
|
||||
static nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>>
|
||||
static nsRefPtr<MediaPromise>
|
||||
CreateAndReject(RejectValueType aRejectValue, const char* aRejectSite)
|
||||
{
|
||||
nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>> p =
|
||||
new MediaPromise<ResolveValueT, RejectValueT>(aRejectSite);
|
||||
nsRefPtr<MediaPromise> p = new MediaPromise(aRejectSite);
|
||||
p->Reject(aRejectValue, aRejectSite);
|
||||
return p;
|
||||
}
|
||||
@ -246,6 +245,8 @@ public:
|
||||
ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer);
|
||||
mHaveConsumer = true;
|
||||
ThenValueBase* thenValue = new ThenValue<TargetType, ThisType, ResolveMethodType,
|
||||
RejectMethodType>(aResponseTarget, aThisVal,
|
||||
aResolveMethod, aRejectMethod,
|
||||
@ -262,6 +263,8 @@ public:
|
||||
void ChainTo(already_AddRefed<MediaPromise> aChainedPromise, const char* aCallSite)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer);
|
||||
mHaveConsumer = true;
|
||||
nsRefPtr<MediaPromise> chainedPromise = aChainedPromise;
|
||||
PROMISE_LOG("%s invoking Chain() [this=%p, chainedPromise=%p, isPending=%d]",
|
||||
aCallSite, this, chainedPromise.get(), (int) IsPending());
|
||||
@ -330,6 +333,7 @@ protected:
|
||||
Maybe<RejectValueType> mRejectValue;
|
||||
nsTArray<ThenValueBase*> mThenValues;
|
||||
nsTArray<nsRefPtr<MediaPromise>> mChainedPromises;
|
||||
bool mHaveConsumer;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -20,7 +20,7 @@ namespace mozilla {
|
||||
|
||||
class SharedThreadPool;
|
||||
|
||||
typedef MediaPromise<bool, bool> ShutdownPromise;
|
||||
typedef MediaPromise<bool, bool, false> ShutdownPromise;
|
||||
|
||||
// Abstracts executing runnables in order in a thread pool. The runnables
|
||||
// dispatched to the MediaTaskQueue will be executed in the order in which
|
||||
|
Loading…
Reference in New Issue
Block a user