зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1263307 P3 Move ServiceWorker update logic into central place in ServiceWorkerRegistrationInfo methods. r=jdm
This commit is contained in:
Родитель
a9a4f7363c
Коммит
b3e4dd4541
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "ServiceWorkerInfo.h"
|
#include "ServiceWorkerInfo.h"
|
||||||
|
|
||||||
|
#include "ServiceWorkerScriptCache.h"
|
||||||
|
|
||||||
BEGIN_WORKERS_NAMESPACE
|
BEGIN_WORKERS_NAMESPACE
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
|
NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
|
||||||
|
@ -139,6 +141,9 @@ ServiceWorkerInfo::UpdateState(ServiceWorkerState aState)
|
||||||
mState = aState;
|
mState = aState;
|
||||||
nsCOMPtr<nsIRunnable> r = new ChangeStateUpdater(mInstances, mState);
|
nsCOMPtr<nsIRunnable> r = new ChangeStateUpdater(mInstances, mState);
|
||||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r.forget()));
|
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r.forget()));
|
||||||
|
if (mState == ServiceWorkerState::Redundant) {
|
||||||
|
serviceWorkerScriptCache::PurgeCache(mPrincipal, mCacheName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
|
ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
|
||||||
|
|
|
@ -20,36 +20,19 @@ ServiceWorkerRegistrationInfo::Clear()
|
||||||
|
|
||||||
if (mWaitingWorker) {
|
if (mWaitingWorker) {
|
||||||
mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
|
||||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
|
||||||
mWaitingWorker->CacheName());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to purge the waiting cache.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mWaitingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
|
mWaitingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
|
||||||
mWaitingWorker = nullptr;
|
mWaitingWorker = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mActiveWorker) {
|
if (mActiveWorker) {
|
||||||
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
|
||||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
|
||||||
mActiveWorker->CacheName());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to purge the active cache.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mActiveWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
|
mActiveWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
|
||||||
mActiveWorker = nullptr;
|
mActiveWorker = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER |
|
||||||
MOZ_ASSERT(swm);
|
WhichServiceWorker::WAITING_WORKER |
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(this,
|
WhichServiceWorker::ACTIVE_WORKER);
|
||||||
WhichServiceWorker::INSTALLING_WORKER |
|
|
||||||
WhichServiceWorker::WAITING_WORKER |
|
|
||||||
WhichServiceWorker::ACTIVE_WORKER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(const nsACString& aScope,
|
ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(const nsACString& aScope,
|
||||||
|
@ -204,44 +187,18 @@ ServiceWorkerRegistrationInfo::TryToActivate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ServiceWorkerRegistrationInfo::PurgeActiveWorker()
|
|
||||||
{
|
|
||||||
RefPtr<ServiceWorkerInfo> exitingWorker = mActiveWorker.forget();
|
|
||||||
if (!exitingWorker)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// FIXME(jaoo): Bug 1170543 - Wait for exitingWorker to finish and terminate it.
|
|
||||||
exitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
|
||||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
|
||||||
exitingWorker->CacheName());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to purge the activating cache.");
|
|
||||||
}
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::ACTIVE_WORKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::Activate()
|
ServiceWorkerRegistrationInfo::Activate()
|
||||||
{
|
{
|
||||||
RefPtr<ServiceWorkerInfo> activatingWorker = mWaitingWorker;
|
if (!mWaitingWorker) {
|
||||||
if (!activatingWorker) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PurgeActiveWorker();
|
TransitionWaitingToActive();
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::WAITING_WORKER);
|
|
||||||
|
|
||||||
mActiveWorker = activatingWorker.forget();
|
|
||||||
mWaitingWorker = nullptr;
|
|
||||||
mActiveWorker->UpdateState(ServiceWorkerState::Activating);
|
|
||||||
NotifyListenersOnChange();
|
|
||||||
|
|
||||||
// FIXME(nsm): Unlink appcache if there is one.
|
// FIXME(nsm): Unlink appcache if there is one.
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
swm->CheckPendingReadyPromises();
|
swm->CheckPendingReadyPromises();
|
||||||
|
|
||||||
// "Queue a task to fire a simple event named controllerchange..."
|
// "Queue a task to fire a simple event named controllerchange..."
|
||||||
|
@ -311,8 +268,16 @@ ServiceWorkerRegistrationInfo::IsLastUpdateCheckTimeOverOneDay() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::NotifyListenersOnChange()
|
ServiceWorkerRegistrationInfo::NotifyListenersOnChange(WhichServiceWorker aChangedWorkers)
|
||||||
{
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(aChangedWorkers & (WhichServiceWorker::INSTALLING_WORKER |
|
||||||
|
WhichServiceWorker::WAITING_WORKER |
|
||||||
|
WhichServiceWorker::ACTIVE_WORKER));
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
swm->InvalidateServiceWorkerRegistrationWorker(this, aChangedWorkers);
|
||||||
|
|
||||||
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> listeners(mListeners);
|
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> listeners(mListeners);
|
||||||
for (size_t index = 0; index < listeners.Length(); ++index) {
|
for (size_t index = 0; index < listeners.Length(); ++index) {
|
||||||
listeners[index]->OnChange();
|
listeners[index]->OnChange();
|
||||||
|
@ -389,24 +354,97 @@ ServiceWorkerRegistrationInfo::GetActive() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::SetInstalling(ServiceWorkerInfo* aServiceWorker)
|
ServiceWorkerRegistrationInfo::ClearInstalling()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
mInstallingWorker = aServiceWorker;
|
|
||||||
|
if (!mInstallingWorker) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
mInstallingWorker = nullptr;
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::SetWaiting(ServiceWorkerInfo* aServiceWorker)
|
ServiceWorkerRegistrationInfo::SetInstalling(ServiceWorkerInfo* aServiceWorker)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
mWaitingWorker = aServiceWorker;
|
MOZ_ASSERT(aServiceWorker);
|
||||||
|
MOZ_ASSERT(!mInstallingWorker);
|
||||||
|
MOZ_ASSERT(mWaitingWorker != aServiceWorker);
|
||||||
|
MOZ_ASSERT(mActiveWorker != aServiceWorker);
|
||||||
|
|
||||||
|
mInstallingWorker = aServiceWorker;
|
||||||
|
mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistrationInfo::TransitionInstallingToWaiting()
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(mInstallingWorker);
|
||||||
|
|
||||||
|
if (mWaitingWorker) {
|
||||||
|
MOZ_ASSERT(mInstallingWorker->CacheName() != mWaitingWorker->CacheName());
|
||||||
|
mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
}
|
||||||
|
|
||||||
|
mWaitingWorker = mInstallingWorker.forget();
|
||||||
|
mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER |
|
||||||
|
WhichServiceWorker::WAITING_WORKER);
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
swm->StoreRegistration(mPrincipal, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::SetActive(ServiceWorkerInfo* aServiceWorker)
|
ServiceWorkerRegistrationInfo::SetActive(ServiceWorkerInfo* aServiceWorker)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(aServiceWorker);
|
||||||
|
|
||||||
|
// TODO: Assert installing, waiting, and active are nullptr once the SWM
|
||||||
|
// moves to the parent process. After that happens this code will
|
||||||
|
// only run for browser initialization and not for cross-process
|
||||||
|
// overrides.
|
||||||
|
MOZ_ASSERT(mInstallingWorker != aServiceWorker);
|
||||||
|
MOZ_ASSERT(mWaitingWorker != aServiceWorker);
|
||||||
|
MOZ_ASSERT(mActiveWorker != aServiceWorker);
|
||||||
|
|
||||||
|
if (mActiveWorker) {
|
||||||
|
MOZ_ASSERT(aServiceWorker->CacheName() != mActiveWorker->CacheName());
|
||||||
|
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The active worker is being overriden due to initial load or
|
||||||
|
// another process activating a worker. Move straight to the
|
||||||
|
// Activated state.
|
||||||
mActiveWorker = aServiceWorker;
|
mActiveWorker = aServiceWorker;
|
||||||
|
mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::ACTIVE_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistrationInfo::TransitionWaitingToActive()
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(mWaitingWorker);
|
||||||
|
|
||||||
|
if (mActiveWorker) {
|
||||||
|
MOZ_ASSERT(mWaitingWorker->CacheName() != mActiveWorker->CacheName());
|
||||||
|
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are transitioning from waiting to active normally, so go to
|
||||||
|
// the activating state.
|
||||||
|
mActiveWorker = mWaitingWorker.forget();
|
||||||
|
mActiveWorker->UpdateState(ServiceWorkerState::Activating);
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::WAITING_WORKER |
|
||||||
|
WhichServiceWorker::ACTIVE_WORKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
END_WORKERS_NAMESPACE
|
END_WORKERS_NAMESPACE
|
||||||
|
|
|
@ -91,9 +91,6 @@ public:
|
||||||
void
|
void
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
void
|
|
||||||
PurgeActiveWorker();
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TryToActivateAsync();
|
TryToActivateAsync();
|
||||||
|
|
||||||
|
@ -113,7 +110,7 @@ public:
|
||||||
IsLastUpdateCheckTimeOverOneDay() const;
|
IsLastUpdateCheckTimeOverOneDay() const;
|
||||||
|
|
||||||
void
|
void
|
||||||
NotifyListenersOnChange();
|
NotifyListenersOnChange(WhichServiceWorker aChangedWorkers);
|
||||||
|
|
||||||
void
|
void
|
||||||
MaybeScheduleTimeCheckAndUpdate();
|
MaybeScheduleTimeCheckAndUpdate();
|
||||||
|
@ -133,14 +130,34 @@ public:
|
||||||
ServiceWorkerInfo*
|
ServiceWorkerInfo*
|
||||||
GetActive() const;
|
GetActive() const;
|
||||||
|
|
||||||
|
// Remove an existing installing worker, if present. The worker will
|
||||||
|
// be transitioned to the Redundant state.
|
||||||
|
void
|
||||||
|
ClearInstalling();
|
||||||
|
|
||||||
|
// Set a new installing worker. This may only be called if there is no
|
||||||
|
// existing installing worker. The worker is transitioned to the Installing
|
||||||
|
// state.
|
||||||
void
|
void
|
||||||
SetInstalling(ServiceWorkerInfo* aServiceWorker);
|
SetInstalling(ServiceWorkerInfo* aServiceWorker);
|
||||||
|
|
||||||
|
// Transition the current installing worker to be the waiting worker. The
|
||||||
|
// workers state is updated to Installed.
|
||||||
void
|
void
|
||||||
SetWaiting(ServiceWorkerInfo* aServiceWorker);
|
TransitionInstallingToWaiting();
|
||||||
|
|
||||||
|
// Override the current active worker. This is used during browser
|
||||||
|
// initialization to load persisted workers. Its also used to propagate
|
||||||
|
// active workers across child processes in e10s. This second use will
|
||||||
|
// go away once the ServiceWorkerManager moves to the parent process.
|
||||||
|
// The worker is transitioned to the Activated state.
|
||||||
void
|
void
|
||||||
SetActive(ServiceWorkerInfo* aServiceWorker);
|
SetActive(ServiceWorkerInfo* aServiceWorker);
|
||||||
|
|
||||||
|
// Transition the current waiting worker to be the new active worker. The
|
||||||
|
// worker is updated to the Activating state.
|
||||||
|
void
|
||||||
|
TransitionWaitingToActive();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace workers
|
} // namespace workers
|
||||||
|
|
|
@ -150,19 +150,9 @@ ServiceWorkerUpdateJob::FailUpdateJob(ErrorResult& aRv)
|
||||||
mServiceWorker->CacheName());
|
mServiceWorker->CacheName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mRegistration->ClearInstalling();
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
|
||||||
if (mRegistration->GetInstalling()) {
|
|
||||||
mRegistration->GetInstalling()->UpdateState(ServiceWorkerState::Redundant);
|
|
||||||
serviceWorkerScriptCache::PurgeCache(mRegistration->mPrincipal,
|
|
||||||
mRegistration->GetInstalling()->CacheName());
|
|
||||||
mRegistration->SetInstalling(nullptr);
|
|
||||||
if (swm) {
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
|
||||||
WhichServiceWorker::INSTALLING_WORKER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (swm) {
|
if (swm) {
|
||||||
swm->MaybeRemoveRegistration(mRegistration);
|
swm->MaybeRemoveRegistration(mRegistration);
|
||||||
}
|
}
|
||||||
|
@ -422,12 +412,6 @@ ServiceWorkerUpdateJob::Install()
|
||||||
MOZ_ASSERT(mServiceWorker);
|
MOZ_ASSERT(mServiceWorker);
|
||||||
mRegistration->SetInstalling(mServiceWorker);
|
mRegistration->SetInstalling(mServiceWorker);
|
||||||
mServiceWorker = nullptr;
|
mServiceWorker = nullptr;
|
||||||
mRegistration->GetInstalling()->UpdateState(ServiceWorkerState::Installing);
|
|
||||||
mRegistration->NotifyListenersOnChange();
|
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
|
||||||
WhichServiceWorker::INSTALLING_WORKER);
|
|
||||||
|
|
||||||
// Step 6 of the Install algorithm resolving the job promise.
|
// Step 6 of the Install algorithm resolving the job promise.
|
||||||
InvokeResultCallbacks(NS_OK);
|
InvokeResultCallbacks(NS_OK);
|
||||||
|
@ -435,6 +419,8 @@ ServiceWorkerUpdateJob::Install()
|
||||||
// The job promise cannot be rejected after this point, but the job can
|
// The job promise cannot be rejected after this point, but the job can
|
||||||
// still fail; e.g. if the install event handler throws, etc.
|
// still fail; e.g. if the install event handler throws, etc.
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
|
||||||
// fire the updatefound event
|
// fire the updatefound event
|
||||||
nsCOMPtr<nsIRunnable> upr =
|
nsCOMPtr<nsIRunnable> upr =
|
||||||
NS_NewRunnableMethodWithArg<RefPtr<ServiceWorkerRegistrationInfo>>(
|
NS_NewRunnableMethodWithArg<RefPtr<ServiceWorkerRegistrationInfo>>(
|
||||||
|
@ -471,8 +457,6 @@ ServiceWorkerUpdateJob::ContinueAfterInstallEvent(bool aInstallEventSuccess)
|
||||||
|
|
||||||
MOZ_ASSERT(mRegistration->GetInstalling());
|
MOZ_ASSERT(mRegistration->GetInstalling());
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
|
|
||||||
// Continue executing the Install algorithm at step 12.
|
// Continue executing the Install algorithm at step 12.
|
||||||
|
|
||||||
// "If installFailed is true"
|
// "If installFailed is true"
|
||||||
|
@ -482,22 +466,7 @@ ServiceWorkerUpdateJob::ContinueAfterInstallEvent(bool aInstallEventSuccess)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "If registration's waiting worker is not null"
|
mRegistration->TransitionInstallingToWaiting();
|
||||||
if (mRegistration->GetWaiting()) {
|
|
||||||
mRegistration->GetWaiting()->WorkerPrivate()->TerminateWorker();
|
|
||||||
mRegistration->GetWaiting()->UpdateState(ServiceWorkerState::Redundant);
|
|
||||||
serviceWorkerScriptCache::PurgeCache(mRegistration->mPrincipal,
|
|
||||||
mRegistration->GetWaiting()->CacheName());
|
|
||||||
}
|
|
||||||
|
|
||||||
mRegistration->SetWaiting(mRegistration->GetInstalling());
|
|
||||||
mRegistration->SetInstalling(nullptr);
|
|
||||||
mRegistration->GetWaiting()->UpdateState(ServiceWorkerState::Installed);
|
|
||||||
mRegistration->NotifyListenersOnChange();
|
|
||||||
swm->StoreRegistration(mPrincipal, mRegistration);
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
|
||||||
WhichServiceWorker::INSTALLING_WORKER |
|
|
||||||
WhichServiceWorker::WAITING_WORKER);
|
|
||||||
|
|
||||||
Finish(NS_OK);
|
Finish(NS_OK);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче