Bug 1328130. Part 1 - add ->Track().
MozReview-Commit-ID: FW7Urv6nyOS
--- a/xpcom/threads/MozPromise.h
+++ b/xpcom/threads/MozPromise.h
@@ -111,16 +111,17 @@ class MozPromiseRefcountable
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MozPromiseRefcountable)
protected:
virtual ~MozPromiseRefcountable() {}
};
template<typename T> class MozPromiseHolder;
+template<typename T> class MozPromiseRequestHolder;
template<typename ResolveValueT, typename RejectValueT, bool IsExclusive>
class MozPromise : public MozPromiseRefcountable
{
public:
typedef ResolveValueT ResolveValueType;
typedef RejectValueT RejectValueType;
class ResolveOrRejectValue
{
@@ -744,20 +745,33 @@ private:
"<completion promise>", true /* aIsCompletionPromise */);
thenValue->mCompletionPromise = p;
// Note ThenInternal() might nullify mCompletionPromise before return.
// So we need to return p instead of mCompletionPromise.
mReceiver->ThenInternal(mResponseThread, thenValue, mCallSite);
return p;
}
- // Allow calling ->Then() again for more promise chaining.
- RefPtr<MozPromise> operator->()
+ template <typename... Ts>
+ auto Then(Ts&&... aArgs)
+ -> decltype(DeclVal<MozPromise>().Then(Forward<Ts>(aArgs)...))
+ {
+ return static_cast<RefPtr<MozPromise>>(*this)->Then(Forward<Ts>(aArgs)...);
+ }
+
+ void Track(MozPromiseRequestHolder<MozPromise>& aRequestHolder)
{
- return *this;
+ aRequestHolder.Track(*this);
+ }
+
+ // Allow calling ->Then() again for more promise chaining or ->Track() to
+ // end chaining and track the request for future disconnection.
+ ThenCommand* operator->()
+ {
+ return this;
}
private:
AbstractThread* mResponseThread;
const char* mCallSite;
RefPtr<ThenValueBase> mThenValue;
MozPromise* mReceiver;
};
@@ -1053,16 +1067,22 @@ public:
}
void Begin(typename PromiseType::Request* aRequest)
{
MOZ_DIAGNOSTIC_ASSERT(!Exists());
mRequest = aRequest;
}
+ void Track(RefPtr<typename PromiseType::Request>&& aRequest)
+ {
+ MOZ_DIAGNOSTIC_ASSERT(!Exists());
+ mRequest = Move(aRequest);
+ }
+
void Complete()
{
MOZ_DIAGNOSTIC_ASSERT(Exists());
mRequest = nullptr;
}
// Disconnects and forgets an outstanding promise. The resolve/reject methods
// will never be called.