gecko-dev/dom/serviceworkers/ServiceWorkerRegistrationChild.cpp
Blake Kaplan 13fc0d95f9 Bug 1510809 - Fire updatefound correctly for SWC.register r=asuth
Currently, we are required to fire updatefound in three cases:

  * When a "soft" update finds an update.
  * When a call to ServiceWorkerRegistration.update finds an update.
  * When ServiceWorkerContainer.register registers a ServiceWorker.

In the first case, there are no requirements on the timing of the event. For
the second two cases, however, the promise returned by update or register
needs to resolve before updatefound is dispatched. We hack around the first
case by explicitly counting the calls to update and only dispatching
updatefound when the final promise resolves. In the case of SWC.register, the
ServiceWorkerRegistration object might not even exist when it notices that we
need to fire updatefound, which suggests that we need some code to tell it
when to fire the event; except that in the soft update case, there is no
obvious place to do so. So, the easiest way to resolve this is to have the
parent process tell the ServiceWorkerRegistration when to fire updatefound
itself. This way, we don't rely on any tricky timing and everything is
consistent with itself.

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

--HG--
extra : moz-landing-system : lando
2018-11-29 23:06:32 +00:00

92 lines
2.0 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ServiceWorkerRegistrationChild.h"
#include "RemoteServiceWorkerRegistrationImpl.h"
namespace mozilla {
namespace dom {
using mozilla::ipc::IPCResult;
void
ServiceWorkerRegistrationChild::ActorDestroy(ActorDestroyReason aReason)
{
if (mWorkerHolderToken) {
mWorkerHolderToken->RemoveListener(this);
mWorkerHolderToken = nullptr;
}
if (mOwner) {
mOwner->RevokeActor(this);
MOZ_DIAGNOSTIC_ASSERT(!mOwner);
}
}
IPCResult
ServiceWorkerRegistrationChild::RecvUpdateState(const IPCServiceWorkerRegistrationDescriptor& aDescriptor)
{
if (mOwner) {
mOwner->UpdateState(ServiceWorkerRegistrationDescriptor(aDescriptor));
}
return IPC_OK();
}
IPCResult
ServiceWorkerRegistrationChild::RecvFireUpdateFound()
{
if (mOwner) {
mOwner->FireUpdateFound();
}
return IPC_OK();
}
void
ServiceWorkerRegistrationChild::WorkerShuttingDown()
{
MaybeStartTeardown();
}
ServiceWorkerRegistrationChild::ServiceWorkerRegistrationChild(WorkerHolderToken* aWorkerHolderToken)
: mWorkerHolderToken(aWorkerHolderToken)
, mOwner(nullptr)
, mTeardownStarted(false)
{
if (mWorkerHolderToken) {
mWorkerHolderToken->AddListener(this);
}
}
void
ServiceWorkerRegistrationChild::SetOwner(RemoteServiceWorkerRegistrationImpl* aOwner)
{
MOZ_DIAGNOSTIC_ASSERT(!mOwner);
MOZ_DIAGNOSTIC_ASSERT(aOwner);
mOwner = aOwner;
}
void
ServiceWorkerRegistrationChild::RevokeOwner(RemoteServiceWorkerRegistrationImpl* aOwner)
{
MOZ_DIAGNOSTIC_ASSERT(mOwner);
MOZ_DIAGNOSTIC_ASSERT(aOwner == mOwner);
mOwner = nullptr;
}
void
ServiceWorkerRegistrationChild::MaybeStartTeardown()
{
if (mTeardownStarted) {
return;
}
mTeardownStarted = true;
Unused << SendTeardown();
}
} // namespace dom
} // namespace mozilla