Bug 1256428 P11 Don't coalesce SW jobs after the existing job has already resolved its promise. r=jdm

This commit is contained in:
Ben Kelly 2016-04-06 13:27:23 -07:00
Родитель 6bdc298a74
Коммит aefe22fcb0
3 изменённых файлов: 22 добавлений и 3 удалений

Просмотреть файл

@ -32,6 +32,12 @@ ServiceWorkerJob2::Canceled() const
return mCanceled; return mCanceled;
} }
bool
ServiceWorkerJob2::ResultCallbacksInvoked() const
{
return mResultCallbacksInvoked;
}
bool bool
ServiceWorkerJob2::IsEquivalentTo(ServiceWorkerJob2* aJob) const ServiceWorkerJob2::IsEquivalentTo(ServiceWorkerJob2* aJob) const
{ {
@ -51,7 +57,7 @@ ServiceWorkerJob2::AppendResultCallback(Callback* aCallback)
MOZ_ASSERT(aCallback); MOZ_ASSERT(aCallback);
MOZ_ASSERT(mFinalCallback != aCallback); MOZ_ASSERT(mFinalCallback != aCallback);
MOZ_ASSERT(!mResultCallbackList.Contains(aCallback)); MOZ_ASSERT(!mResultCallbackList.Contains(aCallback));
// TODO: handle the case where InvokeResultCallback() has already been called MOZ_ASSERT(!mResultCallbacksInvoked);
mResultCallbackList.AppendElement(aCallback); mResultCallbackList.AppendElement(aCallback);
} }
@ -123,6 +129,7 @@ ServiceWorkerJob2::ServiceWorkerJob2(Type aType,
, mScriptSpec(aScriptSpec) , mScriptSpec(aScriptSpec)
, mState(State::Initial) , mState(State::Initial)
, mCanceled(false) , mCanceled(false)
, mResultCallbacksInvoked(false)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
MOZ_ASSERT(mPrincipal); MOZ_ASSERT(mPrincipal);
@ -136,6 +143,7 @@ ServiceWorkerJob2::~ServiceWorkerJob2()
// Jobs must finish or never be started. Destroying an actively running // Jobs must finish or never be started. Destroying an actively running
// job is an error. // job is an error.
MOZ_ASSERT(mState != State::Started); MOZ_ASSERT(mState != State::Started);
MOZ_ASSERT_IF(mState == State::Finished, mResultCallbacksInvoked);
} }
void void
@ -144,6 +152,9 @@ ServiceWorkerJob2::InvokeResultCallbacks(ErrorResult& aRv)
AssertIsOnMainThread(); AssertIsOnMainThread();
MOZ_ASSERT(mState == State::Started); MOZ_ASSERT(mState == State::Started);
MOZ_ASSERT(!mResultCallbacksInvoked);
mResultCallbacksInvoked = true;
nsTArray<RefPtr<Callback>> callbackList; nsTArray<RefPtr<Callback>> callbackList;
callbackList.SwapElements(mResultCallbackList); callbackList.SwapElements(mResultCallbackList);
@ -191,7 +202,9 @@ ServiceWorkerJob2::Finish(ErrorResult& aRv)
// The final callback may drop the last ref to this object. // The final callback may drop the last ref to this object.
RefPtr<ServiceWorkerJob2> kungFuDeathGrip = this; RefPtr<ServiceWorkerJob2> kungFuDeathGrip = this;
if (!mResultCallbacksInvoked) {
InvokeResultCallbacks(aRv); InvokeResultCallbacks(aRv);
}
mState = State::Finished; mState = State::Finished;

Просмотреть файл

@ -66,6 +66,11 @@ public:
bool bool
Canceled() const; Canceled() const;
// Determine if the result callbacks have already been called. This is
// equivalent to the spec checked to see if the job promise has settled.
bool
ResultCallbacksInvoked() const;
bool bool
IsEquivalentTo(ServiceWorkerJob2* aJob) const; IsEquivalentTo(ServiceWorkerJob2* aJob) const;
@ -137,6 +142,7 @@ private:
nsTArray<RefPtr<Callback>> mResultCallbackList; nsTArray<RefPtr<Callback>> mResultCallbackList;
State mState; State mState;
bool mCanceled; bool mCanceled;
bool mResultCallbacksInvoked;
public: public:
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerJob2) NS_INLINE_DECL_REFCOUNTING(ServiceWorkerJob2)

Просмотреть файл

@ -103,7 +103,7 @@ ServiceWorkerJobQueue2::ScheduleJob(ServiceWorkerJob2* aJob)
MOZ_ASSERT(mJobList[0]->GetState() == ServiceWorkerJob2::State::Started); MOZ_ASSERT(mJobList[0]->GetState() == ServiceWorkerJob2::State::Started);
RefPtr<ServiceWorkerJob2>& tailJob = mJobList[mJobList.Length() - 1]; RefPtr<ServiceWorkerJob2>& tailJob = mJobList[mJobList.Length() - 1];
if (aJob->IsEquivalentTo(tailJob)) { if (!tailJob->ResultCallbacksInvoked() && aJob->IsEquivalentTo(tailJob)) {
tailJob->StealResultCallbacksFrom(aJob); tailJob->StealResultCallbacksFrom(aJob);
return; return;
} }