Bug 1189685 - Part 1: Ensure that the state of all ServiceWorker instances is up to date when dispatching statechange events; r=bkelly

This commit is contained in:
Ehsan Akhgari 2015-10-25 19:30:16 -04:00
Родитель 5273912012
Коммит e2a80ec087
3 изменённых файлов: 38 добавлений и 17 удалений

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

@ -101,16 +101,6 @@ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
aRv = workerPrivate->SendMessageEvent(aCx, aMessage, aTransferable, Move(clientInfo));
}
void
ServiceWorker::QueueStateChangeEvent(ServiceWorkerState aState)
{
nsCOMPtr<nsIRunnable> r =
NS_NewRunnableMethodWithArg<ServiceWorkerState>(this,
&ServiceWorker::DispatchStateChange,
aState);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
}
} // namespace workers
} // namespace dom
} // namespace mozilla

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

@ -55,13 +55,9 @@ public:
void
DispatchStateChange(ServiceWorkerState aState)
{
SetState(aState);
DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
}
void
QueueStateChangeEvent(ServiceWorkerState aState);
#ifdef XP_WIN
#undef PostMessage
#endif

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

@ -4212,6 +4212,42 @@ ServiceWorkerInfo::RemoveWorker(ServiceWorker* aWorker)
mInstances.RemoveElement(aWorker);
}
namespace {
class ChangeStateUpdater final : public nsRunnable
{
public:
ChangeStateUpdater(const nsTArray<ServiceWorker*>& aInstances,
ServiceWorkerState aState)
: mState(aState)
{
for (size_t i = 0; i < aInstances.Length(); ++i) {
mInstances.AppendElement(aInstances[i]);
}
}
NS_IMETHODIMP Run()
{
// We need to update the state of all instances atomically before notifying
// them to make sure that the observed state for all instances inside
// statechange event handlers is correct.
for (size_t i = 0; i < mInstances.Length(); ++i) {
mInstances[i]->SetState(mState);
}
for (size_t i = 0; i < mInstances.Length(); ++i) {
mInstances[i]->DispatchStateChange(mState);
}
return NS_OK;
}
private:
nsAutoTArray<RefPtr<ServiceWorker>, 1> mInstances;
ServiceWorkerState mState;
};
}
void
ServiceWorkerInfo::UpdateState(ServiceWorkerState aState)
{
@ -4228,9 +4264,8 @@ ServiceWorkerInfo::UpdateState(ServiceWorkerState aState)
MOZ_ASSERT_IF(mState == ServiceWorkerState::Activated, aState == ServiceWorkerState::Redundant);
#endif
mState = aState;
for (uint32_t i = 0; i < mInstances.Length(); ++i) {
mInstances[i]->QueueStateChangeEvent(mState);
}
nsCOMPtr<nsIRunnable> r = new ChangeStateUpdater(mInstances, mState);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r.forget())));
}
ServiceWorkerInfo::ServiceWorkerInfo(ServiceWorkerRegistrationInfo* aReg,