Bug 1126465 - Make ThenValueBase inherit from a publicly-usable type, and refcount it. r=mattwoodrow

This commit is contained in:
Bobby Holley 2015-01-28 18:54:10 -08:00
parent 5e7d04b210
commit aba3464b85

View File

@ -81,6 +81,15 @@ public:
return p;
}
class Consumer
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Consumer)
protected:
Consumer() {}
virtual ~Consumer() {}
};
protected:
/*
@ -89,7 +98,7 @@ protected:
* resolved or rejected, a {Resolve,Reject}Runnable is dispatched, which
* invokes the resolve/reject method and then deletes the ThenValue.
*/
class ThenValueBase
class ThenValueBase : public Consumer
{
public:
class ResolveRunnable : public nsRunnable
@ -108,14 +117,12 @@ protected:
{
PROMISE_LOG("ResolveRunnable::Run() [this=%p]", this);
mThenValue->DoResolve(mResolveValue);
delete mThenValue;
mThenValue = nullptr;
return NS_OK;
}
private:
ThenValueBase* mThenValue;
nsRefPtr<ThenValueBase> mThenValue;
ResolveValueType mResolveValue;
};
@ -135,28 +142,20 @@ protected:
{
PROMISE_LOG("RejectRunnable::Run() [this=%p]", this);
mThenValue->DoReject(mRejectValue);
delete mThenValue;
mThenValue = nullptr;
return NS_OK;
}
private:
ThenValueBase* mThenValue;
nsRefPtr<ThenValueBase> mThenValue;
RejectValueType mRejectValue;
};
explicit ThenValueBase(const char* aCallSite) : mCallSite(aCallSite)
{
MOZ_COUNT_CTOR(ThenValueBase);
}
explicit ThenValueBase(const char* aCallSite) : mCallSite(aCallSite) {}
virtual void Dispatch(MediaPromise *aPromise) = 0;
protected:
// This may only be deleted by {Resolve,Reject}Runnable::Run.
virtual ~ThenValueBase() { MOZ_COUNT_DTOR(ThenValueBase); }
virtual void DoResolve(ResolveValueType aResolveValue) = 0;
virtual void DoReject(RejectValueType aRejectValue) = 0;
@ -222,14 +221,26 @@ protected:
virtual void DoResolve(ResolveValueType aResolveValue) MOZ_OVERRIDE
{
InvokeCallbackMethod(mThisVal.get(), mResolveMethod, aResolveValue);
// Null these out after invoking the callback so that any references are
// released predictably on the target thread. Otherwise, they would be
// released on whatever thread last drops its reference to the ThenValue,
// which may or may not be ok.
mResponseTarget = nullptr;
mThisVal = nullptr;
}
virtual void DoReject(RejectValueType aRejectValue) MOZ_OVERRIDE
{
InvokeCallbackMethod(mThisVal.get(), mRejectMethod, aRejectValue);
}
virtual ~ThenValue() {}
// Null these out after invoking the callback so that any references are
// released predictably on the target thread. Otherwise, they would be
// released on whatever thread last drops its reference to the ThenValue,
// which may or may not be ok.
mResponseTarget = nullptr;
mThisVal = nullptr;
}
private:
nsRefPtr<TargetType> mResponseTarget;
@ -247,12 +258,12 @@ public:
MutexAutoLock lock(mMutex);
MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer);
mHaveConsumer = true;
ThenValueBase* thenValue = new ThenValue<TargetType, ThisType, ResolveMethodType,
RejectMethodType>(aResponseTarget, aThisVal,
aResolveMethod, aRejectMethod,
aCallSite);
nsRefPtr<ThenValueBase> thenValue = new ThenValue<TargetType, ThisType, ResolveMethodType,
RejectMethodType>(aResponseTarget, aThisVal,
aResolveMethod, aRejectMethod,
aCallSite);
PROMISE_LOG("%s invoking Then() [this=%p, thenValue=%p, aThisVal=%p, isPending=%d]",
aCallSite, this, thenValue, aThisVal, (int) IsPending());
aCallSite, this, thenValue.get(), aThisVal, (int) IsPending());
if (!IsPending()) {
thenValue->Dispatch(this);
} else {
@ -331,7 +342,7 @@ protected:
Mutex mMutex;
Maybe<ResolveValueType> mResolveValue;
Maybe<RejectValueType> mRejectValue;
nsTArray<ThenValueBase*> mThenValues;
nsTArray<nsRefPtr<ThenValueBase>> mThenValues;
nsTArray<nsRefPtr<MediaPromise>> mChainedPromises;
bool mHaveConsumer;
};