Bug 1231213 - Have ServiceWorkerManager block shutdown on "profile-change-teardown" when in the parent process with parent intercept enabled. r=asuth

Differential Revision: https://phabricator.services.mozilla.com/D26166

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Perry Jiang 2019-08-13 04:57:21 +00:00
Родитель 1e8e727d16
Коммит 8378ead525
3 изменённых файлов: 72 добавлений и 5 удалений

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

@ -150,6 +150,7 @@ void ServiceWorkerInfo::UpdateState(ServiceWorkerState aState) {
mDescriptor.SetState(aState);
if (State() == ServiceWorkerState::Redundant) {
serviceWorkerScriptCache::PurgeCache(mPrincipal, mCacheName);
mServiceWorkerPrivate->NoteDeadServiceWorkerInfo();
}
}

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

@ -25,6 +25,7 @@
#include "nsDebug.h"
#include "nsISupportsPrimitives.h"
#include "nsIPermissionManager.h"
#include "nsXULAppAPI.h"
#include "jsapi.h"
@ -76,6 +77,7 @@
#include "ServiceWorkerRegistrar.h"
#include "ServiceWorkerRegistration.h"
#include "ServiceWorkerScriptCache.h"
#include "ServiceWorkerShutdownBlocker.h"
#include "ServiceWorkerEvents.h"
#include "ServiceWorkerUnregisterJob.h"
#include "ServiceWorkerUpdateJob.h"
@ -259,6 +261,36 @@ class TeardownRunnable final : public Runnable {
RefPtr<ServiceWorkerManagerChild> mActor;
};
bool ServiceWorkersAreCrossProcess() {
return ServiceWorkerParentInterceptEnabled() && XRE_IsE10sParentProcess();
}
const char* GetXPCOMShutdownTopic() {
if (ServiceWorkersAreCrossProcess()) {
return "profile-change-teardown";
}
return NS_XPCOM_SHUTDOWN_OBSERVER_ID;
}
already_AddRefed<nsIAsyncShutdownClient> GetAsyncShutdownBarrier() {
AssertIsOnMainThread();
if (!ServiceWorkersAreCrossProcess()) {
return nullptr;
}
nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
MOZ_ASSERT(svc);
nsCOMPtr<nsIAsyncShutdownClient> barrier;
DebugOnly<nsresult> rv =
svc->GetProfileChangeTeardown(getter_AddRefs(barrier));
MOZ_ASSERT(NS_SUCCEEDED(rv));
return barrier.forget();
}
} // namespace
//////////////////////////
@ -280,15 +312,40 @@ ServiceWorkerManager::ServiceWorkerManager()
ServiceWorkerManager::~ServiceWorkerManager() {
// The map will assert if it is not empty when destroyed.
mRegistrationInfos.Clear();
MOZ_ASSERT(!mActor);
if (!ServiceWorkersAreCrossProcess()) {
MOZ_ASSERT(!mActor);
}
}
void ServiceWorkerManager::BlockShutdownOn(
GenericNonExclusivePromise* aPromise) {
AssertIsOnMainThread();
// This may be called when in non-e10s mode with parent-intercept enabled.
if (!ServiceWorkersAreCrossProcess()) {
return;
}
MOZ_ASSERT(mShutdownBlocker);
MOZ_ASSERT(aPromise);
mShutdownBlocker->WaitOnPromise(aPromise);
}
void ServiceWorkerManager::Init(ServiceWorkerRegistrar* aRegistrar) {
nsCOMPtr<nsIAsyncShutdownClient> shutdownBarrier = GetAsyncShutdownBarrier();
if (shutdownBarrier) {
mShutdownBlocker =
ServiceWorkerShutdownBlocker::CreateAndRegisterOn(shutdownBarrier);
MOZ_ASSERT(mShutdownBlocker);
}
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
DebugOnly<nsresult> rv;
rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
false /* ownsWeak */);
rv = obs->AddObserver(this, GetXPCOMShutdownTopic(), false /* ownsWeak */);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
@ -451,9 +508,13 @@ void ServiceWorkerManager::MaybeStartShutdown() {
it1.UserData()->mInfos.Clear();
}
if (mShutdownBlocker) {
mShutdownBlocker->StopAcceptingPromises();
}
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
obs->RemoveObserver(this, GetXPCOMShutdownTopic());
if (XRE_IsParentProcess()) {
obs->RemoveObserver(this, CLEAR_ORIGIN_DATA);
@ -2737,7 +2798,7 @@ ServiceWorkerManager::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
if (strcmp(aTopic, GetXPCOMShutdownTopic()) == 0) {
MaybeStartShutdown();
return NS_OK;
}

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

@ -51,6 +51,7 @@ class ServiceWorkerJobQueue;
class ServiceWorkerManagerChild;
class ServiceWorkerPrivate;
class ServiceWorkerRegistrar;
class ServiceWorkerShutdownBlocker;
class ServiceWorkerUpdateFinishCallback {
protected:
@ -280,6 +281,8 @@ class ServiceWorkerManager final : public nsIServiceWorkerManager,
void NoteInheritedController(const ClientInfo& aClientInfo,
const ServiceWorkerDescriptor& aController);
void BlockShutdownOn(GenericNonExclusivePromise* aPromise);
nsresult GetClientRegistration(
const ClientInfo& aClientInfo,
ServiceWorkerRegistrationInfo** aRegistrationInfo);
@ -385,6 +388,8 @@ class ServiceWorkerManager final : public nsIServiceWorkerManager,
const nsAString& aTag, const nsAString& aIcon,
const nsAString& aData,
const nsAString& aBehavior);
RefPtr<ServiceWorkerShutdownBlocker> mShutdownBlocker;
};
} // namespace dom