Diff
Modified: trunk/LayoutTests/ChangeLog (226273 => 226274)
--- trunk/LayoutTests/ChangeLog 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/LayoutTests/ChangeLog 2017-12-22 21:17:46 UTC (rev 226274)
@@ -1,3 +1,15 @@
+2017-12-22 Chris Dumez <[email protected]>
+
+ [Service Workers] Implement "Soft Update" algorithm
+ https://bugs.webkit.org/show_bug.cgi?id=180702
+ <rdar://problem/36163461>
+
+ Reviewed by Youenn Fablet.
+
+ Unskip soft update WPT test that no longer times out.
+
+ * TestExpectations:
+
2017-12-21 Ryosuke Niwa <[email protected]>
REGRESSION(r223678): Cannot copy & paste a web page content into Yahoo! Mail
Modified: trunk/LayoutTests/TestExpectations (226273 => 226274)
--- trunk/LayoutTests/TestExpectations 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/LayoutTests/TestExpectations 2017-12-22 21:17:46 UTC (rev 226274)
@@ -154,7 +154,6 @@
imported/w3c/web-platform-tests/service-workers/service-worker/postmessage-msgport-to-client.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/respond-with-body-accessed-response.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html [ Skip ]
-imported/w3c/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/update-bytecheck.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/update-recovery.https.html [ Skip ]
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (226273 => 226274)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2017-12-22 21:17:46 UTC (rev 226274)
@@ -1,3 +1,15 @@
+2017-12-22 Chris Dumez <[email protected]>
+
+ [Service Workers] Implement "Soft Update" algorithm
+ https://bugs.webkit.org/show_bug.cgi?id=180702
+ <rdar://problem/36163461>
+
+ Reviewed by Youenn Fablet.
+
+ Rebaseline Soft Update WPT test now that it is passing.
+
+ * web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https-expected.txt:
+
2017-12-21 Youenn Fablet <[email protected]>
ServiceWorkerThreadProxy should set the correct cookie and cache partitioning options
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https-expected.txt (226273 => 226274)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https-expected.txt 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https-expected.txt 2017-12-22 21:17:46 UTC (rev 226274)
@@ -1,6 +1,3 @@
+PASS Update should be triggered after a navigation fetch event.
-Harness Error (TIMEOUT), message = null
-
-TIMEOUT Update should be triggered after a navigation fetch event. Test timed out
-
Modified: trunk/Source/WebCore/ChangeLog (226273 => 226274)
--- trunk/Source/WebCore/ChangeLog 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/ChangeLog 2017-12-22 21:17:46 UTC (rev 226274)
@@ -1,3 +1,55 @@
+2017-12-22 Chris Dumez <[email protected]>
+
+ [Service Workers] Implement "Soft Update" algorithm
+ https://bugs.webkit.org/show_bug.cgi?id=180702
+ <rdar://problem/36163461>
+
+ Reviewed by Youenn Fablet.
+
+ Implement "Soft Update" algorithm:
+ - https://w3c.github.io/ServiceWorker/#soft-update-algorithm
+
+ Call softUpdate at the end of "Handle Fetch", as per:
+ - https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm
+
+ No new tests, rebaselined existing test.
+
+ * dom/ScriptExecutionContext.cpp:
+ (WebCore::ScriptExecutionContext::postTaskTo):
+ * dom/ScriptExecutionContext.h:
+ * workers/service/SWClientConnection.cpp:
+ (WebCore::SWClientConnection::failedFetchingScript):
+ (WebCore::SWClientConnection::registrationJobResolvedInServer):
+ (WebCore::SWClientConnection::startScriptFetchForServer):
+ * workers/service/SWClientConnection.h:
+ * workers/service/ServiceWorkerContainer.cpp:
+ (WebCore::ServiceWorkerContainer::updateRegistration):
+ (WebCore::ServiceWorkerContainer::jobFailedWithException):
+ (WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
+ (WebCore::ServiceWorkerContainer::jobResolvedWithUnregistrationResult):
+ (WebCore::ServiceWorkerContainer::startScriptFetchForJob):
+ (WebCore::ServiceWorkerContainer::jobFailedLoadingScript):
+ * workers/service/ServiceWorkerContainer.h:
+ * workers/service/ServiceWorkerJob.cpp:
+ (WebCore::ServiceWorkerJob::ServiceWorkerJob):
+ * workers/service/ServiceWorkerJob.h:
+ (WebCore::ServiceWorkerJob::create):
+ (WebCore::ServiceWorkerJob::data const):
+ (WebCore::ServiceWorkerJob::promise):
+ * workers/service/ServiceWorkerRegistration.cpp:
+ (WebCore::ServiceWorkerRegistration::softUpdate):
+ * workers/service/ServiceWorkerRegistration.h:
+ * workers/service/context/SWContextManager.cpp:
+ (WebCore::SWContextManager::terminateWorker):
+ (WebCore::SWContextManager::postTaskToServiceWorker):
+ * workers/service/context/SWContextManager.h:
+ * workers/service/context/ServiceWorkerFetch.cpp:
+ (WebCore::ServiceWorkerFetch::dispatchFetchEvent):
+ * workers/service/context/ServiceWorkerFetch.h:
+ * workers/service/server/SWServer.cpp:
+ (WebCore::SWServer::startScriptFetch):
+ * workers/service/server/SWServer.h:
+
2017-12-22 Zalan Bujtas <[email protected]>
[RenderTreeBuilder] Move RenderMenuList::addChild() tree mutation to RenderTreeBuilder
Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.cpp (226273 => 226274)
--- trunk/Source/WebCore/dom/ScriptExecutionContext.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -570,10 +570,11 @@
return navigator ? &navigator->serviceWorker() : nullptr;
}
-void ScriptExecutionContext::postTaskTo(const DocumentOrWorkerIdentifier& contextIdentifier, WTF::Function<void(ScriptExecutionContext&)>&& task)
+bool ScriptExecutionContext::postTaskTo(const DocumentOrWorkerIdentifier& contextIdentifier, WTF::Function<void(ScriptExecutionContext&)>&& task)
{
ASSERT(isMainThread());
+ bool wasPosted = false;
switchOn(contextIdentifier, [&] (DocumentIdentifier identifier) {
auto* document = Document::allDocumentsMap().get(identifier);
if (!document)
@@ -581,11 +582,13 @@
document->postTask([task = WTFMove(task)](auto& scope) {
task(scope);
});
+ wasPosted= true;
}, [&](ServiceWorkerIdentifier identifier) {
- SWContextManager::singleton().postTaskToServiceWorker(identifier, [task = WTFMove(task)](auto& scope) {
+ wasPosted = SWContextManager::singleton().postTaskToServiceWorker(identifier, [task = WTFMove(task)](auto& scope) {
task(scope);
});
});
+ return wasPosted;
}
#endif
Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.h (226273 => 226274)
--- trunk/Source/WebCore/dom/ScriptExecutionContext.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -251,7 +251,7 @@
ServiceWorkerContainer* serviceWorkerContainer();
- WEBCORE_EXPORT static void postTaskTo(const DocumentOrWorkerIdentifier&, WTF::Function<void(ScriptExecutionContext&)>&&);
+ WEBCORE_EXPORT static bool postTaskTo(const DocumentOrWorkerIdentifier&, WTF::Function<void(ScriptExecutionContext&)>&&);
#endif
protected:
Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (226273 => 226274)
--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -269,10 +269,8 @@
// FIXME: Fully implement https://w3c.github.io/ServiceWorker/#importscripts.
auto& serviceWorkerGlobalScope = downcast<ServiceWorkerGlobalScope>(*this);
auto& registration = serviceWorkerGlobalScope.registration();
- if (registration.updateViaCache() == ServiceWorkerUpdateViaCache::None
- || (registration.lastUpdateTime() && (WallTime::now() - registration.lastUpdateTime()) > 86400_s)) {
+ if (registration.updateViaCache() == ServiceWorkerUpdateViaCache::None || registration.needsUpdate())
cachePolicy = FetchOptions::Cache::NoCache;
- }
}
#endif
Modified: trunk/Source/WebCore/workers/service/SWClientConnection.cpp (226273 => 226274)
--- trunk/Source/WebCore/workers/service/SWClientConnection.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/SWClientConnection.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -38,6 +38,7 @@
#include "ServiceWorkerJobData.h"
#include "ServiceWorkerRegistration.h"
#include <wtf/CrossThreadCopier.h>
+#include <wtf/Scope.h>
namespace WebCore {
@@ -63,12 +64,11 @@
finishFetchingScriptInServer({ job.data().identifier(), job.data().registrationKey(), script, { } });
}
-void SWClientConnection::failedFetchingScript(ServiceWorkerJob& job, const ResourceError& error)
+void SWClientConnection::failedFetchingScript(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, const ServiceWorkerRegistrationKey& registrationKey, const ResourceError& error)
{
ASSERT(isMainThread());
- ASSERT(m_scheduledJobs.get(job.identifier()) == &job);
- finishFetchingScriptInServer({ job.data().identifier(), job.data().registrationKey(), { }, error });
+ finishFetchingScriptInServer({ jobDataIdentifier, registrationKey, { }, error });
}
void SWClientConnection::jobRejectedInServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, const ExceptionData& exceptionData)
@@ -90,6 +90,11 @@
{
ASSERT(isMainThread());
+ auto guard = WTF::makeScopeExit([this, shouldNotifyWhenResolved, registrationKey = registrationData.key] {
+ if (shouldNotifyWhenResolved == ShouldNotifyWhenResolved::Yes)
+ didResolveRegistrationPromise(registrationKey);
+ });
+
auto job = m_scheduledJobs.take(jobDataIdentifier.jobIdentifier);
if (!job) {
LOG_ERROR("Job %s resolved in server, but was not found", jobDataIdentifier.loggingString().utf8().data());
@@ -96,9 +101,12 @@
return;
}
- ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job, registrationData = registrationData.isolatedCopy(), shouldNotifyWhenResolved](ScriptExecutionContext&) mutable {
+ bool wasPosted = ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job, registrationData = registrationData.isolatedCopy(), shouldNotifyWhenResolved](ScriptExecutionContext&) mutable {
job->resolvedWithRegistration(WTFMove(registrationData), shouldNotifyWhenResolved);
});
+
+ if (wasPosted)
+ guard.release();
}
void SWClientConnection::unregistrationJobResolvedInServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, bool unregistrationResult)
@@ -116,7 +124,7 @@
});
}
-void SWClientConnection::startScriptFetchForServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, FetchOptions::Cache cachePolicy)
+void SWClientConnection::startScriptFetchForServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, const ServiceWorkerRegistrationKey& registrationKey, FetchOptions::Cache cachePolicy)
{
ASSERT(isMainThread());
@@ -124,16 +132,15 @@
if (!job) {
LOG_ERROR("Job %s instructed to start fetch from server, but job was not found", jobDataIdentifier.loggingString().utf8().data());
- // FIXME: Should message back to the server here to signal failure to fetch,
- // but we currently need the registration key to do so, and don't have it here.
- // In the future we'll refactor to have a global, cross-process job identifier that can be used to overcome this.
-
+ failedFetchingScript(jobDataIdentifier, registrationKey, ResourceError { errorDomainWebKitInternal, 0, URL(), ASCIILiteral("Failed to fetch service worker script") });
return;
}
- ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job, cachePolicy](ScriptExecutionContext&) {
+ bool wasPosted = ScriptExecutionContext::postTaskTo(job->contextIdentifier(), [job, cachePolicy](ScriptExecutionContext&) {
job->startScriptFetch(cachePolicy);
});
+ if (!wasPosted)
+ failedFetchingScript(jobDataIdentifier, registrationKey, ResourceError { errorDomainWebKitInternal, 0, job->data().scriptURL, ASCIILiteral("Failed to fetch service worker script") });
}
void SWClientConnection::postMessageToServiceWorkerClient(DocumentIdentifier destinationContextIdentifier, Ref<SerializedScriptValue>&& message, ServiceWorkerData&& sourceData, const String& sourceOrigin)
Modified: trunk/Source/WebCore/workers/service/SWClientConnection.h (226273 => 226274)
--- trunk/Source/WebCore/workers/service/SWClientConnection.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/SWClientConnection.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -70,7 +70,7 @@
void scheduleJob(ServiceWorkerJob&);
void finishedFetchingScript(ServiceWorkerJob&, const String&);
- void failedFetchingScript(ServiceWorkerJob&, const ResourceError&);
+ void failedFetchingScript(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationKey&, const ResourceError&);
virtual void didResolveRegistrationPromise(const ServiceWorkerRegistrationKey&) = 0;
@@ -89,7 +89,7 @@
WEBCORE_EXPORT void jobRejectedInServer(const ServiceWorkerJobDataIdentifier&, const ExceptionData&);
WEBCORE_EXPORT void registrationJobResolvedInServer(const ServiceWorkerJobDataIdentifier&, ServiceWorkerRegistrationData&&, ShouldNotifyWhenResolved);
WEBCORE_EXPORT void unregistrationJobResolvedInServer(const ServiceWorkerJobDataIdentifier&, bool unregistrationResult);
- WEBCORE_EXPORT void startScriptFetchForServer(const ServiceWorkerJobDataIdentifier&, FetchOptions::Cache);
+ WEBCORE_EXPORT void startScriptFetchForServer(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationKey&, FetchOptions::Cache);
WEBCORE_EXPORT void postMessageToServiceWorkerClient(DocumentIdentifier destinationContextIdentifier, Ref<SerializedScriptValue>&& message, ServiceWorkerData&& source, const String& sourceOrigin);
WEBCORE_EXPORT void updateRegistrationState(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&);
WEBCORE_EXPORT void updateWorkerState(ServiceWorkerIdentifier, ServiceWorkerState);
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp (226273 => 226274)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -189,24 +189,23 @@
scheduleJob(ServiceWorkerJob::create(*this, WTFMove(promise), WTFMove(jobData)));
}
-void ServiceWorkerContainer::updateRegistration(const URL& scopeURL, const URL& scriptURL, WorkerType, Ref<DeferredPromise>&& promise)
+void ServiceWorkerContainer::updateRegistration(const URL& scopeURL, const URL& scriptURL, WorkerType, RefPtr<DeferredPromise>&& promise)
{
- auto* context = scriptExecutionContext();
- if (!context || !context->sessionID().isValid()) {
- ASSERT_NOT_REACHED();
- promise->reject(Exception(InvalidStateError));
- return;
- }
+ ASSERT(!m_isStopped);
+ auto& context = *scriptExecutionContext();
+ ASSERT(context.sessionID().isValid());
+
if (!m_swConnection) {
ASSERT_NOT_REACHED();
- promise->reject(Exception(InvalidStateError));
+ if (promise)
+ promise->reject(Exception(InvalidStateError));
return;
}
ServiceWorkerJobData jobData(m_swConnection->serverConnectionIdentifier());
- jobData.clientCreationURL = context->url();
- jobData.topOrigin = SecurityOriginData::fromSecurityOrigin(context->topOrigin());
+ jobData.clientCreationURL = context.url();
+ jobData.topOrigin = SecurityOriginData::fromSecurityOrigin(context.topOrigin());
jobData.type = ServiceWorkerJobType::Update;
jobData.scopeURL = scopeURL;
jobData.scriptURL = scriptURL;
@@ -353,12 +352,20 @@
ASSERT(m_creationThread.ptr() == &Thread::current());
#endif
+ ASSERT_WITH_MESSAGE(job.promise() || job.data().type == ServiceWorkerJobType::Update, "Only soft updates have no promise");
+
+ auto guard = WTF::makeScopeExit([this, &job] {
+ jobDidFinish(job);
+ });
+
+ if (!job.promise())
+ return;
+
if (auto* context = scriptExecutionContext()) {
context->postTask([job = makeRef(job), exception](ScriptExecutionContext&) {
- job->promise().reject(exception);
+ job->promise()->reject(exception);
});
}
- jobDidFinish(job);
}
void ServiceWorkerContainer::scheduleTaskToFireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier identifier)
@@ -376,6 +383,7 @@
#ifndef NDEBUG
ASSERT(m_creationThread.ptr() == &Thread::current());
#endif
+ ASSERT_WITH_MESSAGE(job.promise() || job.data().type == ServiceWorkerJobType::Update, "Only soft updates have no promise");
auto guard = WTF::makeScopeExit([this, &job] {
jobDidFinish(job);
@@ -395,6 +403,11 @@
return;
}
+ if (!job.promise()) {
+ notifyWhenResolvedIfNeeded();
+ return;
+ }
+
scriptExecutionContext()->postTask([this, protectedThis = makeRef(*this), job = makeRef(job), data = "" notifyWhenResolvedIfNeeded = WTFMove(notifyWhenResolvedIfNeeded)](ScriptExecutionContext& context) mutable {
if (isStopped()) {
notifyWhenResolvedIfNeeded();
@@ -405,7 +418,7 @@
LOG(ServiceWorker, "Container %p resolved job with registration %p", this, registration.ptr());
- job->promise().resolve<IDLInterface<ServiceWorkerRegistration>>(WTFMove(registration));
+ job->promise()->resolve<IDLInterface<ServiceWorkerRegistration>>(WTFMove(registration));
notifyWhenResolvedIfNeeded();
});
@@ -417,6 +430,8 @@
ASSERT(m_creationThread.ptr() == &Thread::current());
#endif
+ ASSERT(job.promise());
+
auto guard = WTF::makeScopeExit([this, &job] {
jobDidFinish(job);
});
@@ -428,7 +443,7 @@
}
context->postTask([job = makeRef(job), unregistrationResult](ScriptExecutionContext&) mutable {
- job->promise().resolve<IDLBoolean>(unregistrationResult);
+ job->promise()->resolve<IDLBoolean>(unregistrationResult);
});
}
@@ -444,7 +459,7 @@
if (!context) {
LOG_ERROR("ServiceWorkerContainer::jobResolvedWithRegistration called but the container's ScriptExecutionContext is gone");
callOnMainThread([connection = m_swConnection, job = makeRef(job)] {
- connection->failedFetchingScript(job, { errorDomainWebKitInternal, 0, job->data().scriptURL, ASCIILiteral("Attempt to fetch service worker script with no ScriptExecutionContext") });
+ connection->failedFetchingScript(job->data().identifier(), job->data().registrationKey(), { errorDomainWebKitInternal, 0, job->data().scriptURL, ASCIILiteral("Attempt to fetch service worker script with no ScriptExecutionContext") });
});
jobDidFinish(job);
return;
@@ -471,14 +486,15 @@
#ifndef NDEBUG
ASSERT(m_creationThread.ptr() == &Thread::current());
#endif
+ ASSERT_WITH_MESSAGE(job.promise() || job.data().type == ServiceWorkerJobType::Update, "Only soft updates have no promise");
LOG(ServiceWorker, "SeviceWorkerContainer %p failed fetching script for job %s", this, job.identifier().loggingString().utf8().data());
- if (exception)
- job.promise().reject(*exception);
+ if (exception && job.promise())
+ job.promise()->reject(*exception);
callOnMainThread([connection = m_swConnection, job = makeRef(job), error = error.isolatedCopy()] {
- connection->failedFetchingScript(job, error);
+ connection->failedFetchingScript(job->data().identifier(), job->data().registrationKey(), error);
});
}
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h (226273 => 226274)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -61,7 +61,7 @@
using RegistrationOptions = ServiceWorkerRegistrationOptions;
void addRegistration(const String& scriptURL, const RegistrationOptions&, Ref<DeferredPromise>&&);
void removeRegistration(const URL& scopeURL, Ref<DeferredPromise>&&);
- void updateRegistration(const URL& scopeURL, const URL& scriptURL, WorkerType, Ref<DeferredPromise>&&);
+ void updateRegistration(const URL& scopeURL, const URL& scriptURL, WorkerType, RefPtr<DeferredPromise>&&);
void getRegistration(const String& clientURL, Ref<DeferredPromise>&&);
void scheduleTaskToUpdateRegistrationState(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&);
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp (226273 => 226274)
--- trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -38,7 +38,7 @@
namespace WebCore {
-ServiceWorkerJob::ServiceWorkerJob(ServiceWorkerJobClient& client, Ref<DeferredPromise>&& promise, ServiceWorkerJobData&& jobData)
+ServiceWorkerJob::ServiceWorkerJob(ServiceWorkerJobClient& client, RefPtr<DeferredPromise>&& promise, ServiceWorkerJobData&& jobData)
: m_client(client)
, m_jobData(WTFMove(jobData))
, m_promise(WTFMove(promise))
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerJob.h (226273 => 226274)
--- trunk/Source/WebCore/workers/service/ServiceWorkerJob.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerJob.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -48,7 +48,7 @@
class ServiceWorkerJob : public ThreadSafeRefCounted<ServiceWorkerJob>, public WorkerScriptLoaderClient {
public:
- static Ref<ServiceWorkerJob> create(ServiceWorkerJobClient& client, Ref<DeferredPromise>&& promise, ServiceWorkerJobData&& jobData)
+ static Ref<ServiceWorkerJob> create(ServiceWorkerJobClient& client, RefPtr<DeferredPromise>&& promise, ServiceWorkerJobData&& jobData)
{
return adoptRef(*new ServiceWorkerJob(client, WTFMove(promise), WTFMove(jobData)));
}
@@ -63,8 +63,8 @@
using Identifier = ServiceWorkerJobIdentifier;
Identifier identifier() const { return m_jobData.identifier().jobIdentifier; }
- ServiceWorkerJobData data() const { return m_jobData; }
- DeferredPromise& promise() { return m_promise.get(); }
+ const ServiceWorkerJobData& data() const { return m_jobData; }
+ DeferredPromise* promise() { return m_promise.get(); }
void fetchScriptWithContext(ScriptExecutionContext&, FetchOptions::Cache);
@@ -71,7 +71,7 @@
const DocumentOrWorkerIdentifier& contextIdentifier() { return m_contextIdentifier; }
private:
- ServiceWorkerJob(ServiceWorkerJobClient&, Ref<DeferredPromise>&&, ServiceWorkerJobData&&);
+ ServiceWorkerJob(ServiceWorkerJobClient&, RefPtr<DeferredPromise>&&, ServiceWorkerJobData&&);
// WorkerScriptLoaderClient
void didReceiveResponse(unsigned long identifier, const ResourceResponse&) final;
@@ -81,7 +81,7 @@
Ref<ServiceWorkerJobClient> m_client;
ServiceWorkerJobData m_jobData;
- Ref<DeferredPromise> m_promise;
+ RefPtr<DeferredPromise> m_promise;
bool m_completed { false };
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp (226273 => 226274)
--- trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -144,6 +144,19 @@
m_container->updateRegistration(m_registrationData.scopeURL, newestWorker->scriptURL(), WorkerType::Classic, WTFMove(promise));
}
+void ServiceWorkerRegistration::softUpdate()
+{
+ if (m_isStopped)
+ return;
+
+ auto* newestWorker = getNewestWorker();
+ if (!newestWorker)
+ return;
+
+ // FIXME: Support worker types.
+ m_container->updateRegistration(m_registrationData.scopeURL, newestWorker->scriptURL(), WorkerType::Classic, nullptr);
+}
+
void ServiceWorkerRegistration::unregister(Ref<DeferredPromise>&& promise)
{
if (m_isStopped) {
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.h (226273 => 226274)
--- trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -61,9 +61,13 @@
WallTime lastUpdateTime() const;
void setLastUpdateTime(WallTime);
+ bool needsUpdate() const { return lastUpdateTime() && (WallTime::now() - lastUpdateTime()) > 86400_s; }
+
void update(Ref<DeferredPromise>&&);
void unregister(Ref<DeferredPromise>&&);
+ void softUpdate();
+
using RefCounted::ref;
using RefCounted::deref;
Modified: trunk/Source/WebCore/workers/service/context/SWContextManager.cpp (226273 => 226274)
--- trunk/Source/WebCore/workers/service/context/SWContextManager.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -97,13 +97,13 @@
void SWContextManager::terminateWorker(ServiceWorkerIdentifier identifier, Function<void()>&& completionHandler)
{
- auto* serviceWorker = m_workerMap.get(identifier);
+ auto serviceWorker = m_workerMap.take(identifier);
if (!serviceWorker)
return;
serviceWorker->setTerminatingOrTerminated(true);
- serviceWorker->thread().stop([this, identifier, completionHandler = WTFMove(completionHandler)] {
+ serviceWorker->thread().stop([this, identifier, serviceWorker = WTFMove(serviceWorker), completionHandler = WTFMove(completionHandler)]() mutable {
if (auto* connection = SWContextManager::singleton().connection())
connection->workerTerminated(identifier);
@@ -110,12 +110,9 @@
if (completionHandler)
completionHandler();
- auto worker = m_workerMap.take(identifier);
- ASSERT(worker);
-
// Spin the runloop before releasing the worker thread proxy, as there would otherwise be
// a race towards its destruction.
- callOnMainThread([worker = WTFMove(worker)] { });
+ callOnMainThread([serviceWorker = WTFMove(serviceWorker)] { });
});
}
@@ -125,13 +122,16 @@
apply(*workerThread);
}
-void SWContextManager::postTaskToServiceWorker(ServiceWorkerIdentifier identifier, WTF::Function<void(ServiceWorkerGlobalScope&)>&& task)
+bool SWContextManager::postTaskToServiceWorker(ServiceWorkerIdentifier identifier, WTF::Function<void(ServiceWorkerGlobalScope&)>&& task)
{
- if (auto* serviceWorker = m_workerMap.get(identifier)) {
- serviceWorker->thread().runLoop().postTask([task = WTFMove(task)] (auto& context) {
- task(downcast<ServiceWorkerGlobalScope>(context));
- });
- }
+ auto* serviceWorker = m_workerMap.get(identifier);
+ if (!serviceWorker)
+ return false;
+
+ serviceWorker->thread().runLoop().postTask([task = WTFMove(task)] (auto& context) {
+ task(downcast<ServiceWorkerGlobalScope>(context));
+ });
+ return true;
}
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/service/context/SWContextManager.h (226273 => 226274)
--- trunk/Source/WebCore/workers/service/context/SWContextManager.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -74,7 +74,7 @@
void forEachServiceWorkerThread(const WTF::Function<void(ServiceWorkerThreadProxy&)>&);
- WEBCORE_EXPORT void postTaskToServiceWorker(ServiceWorkerIdentifier, WTF::Function<void(ServiceWorkerGlobalScope&)>&&);
+ WEBCORE_EXPORT bool postTaskToServiceWorker(ServiceWorkerIdentifier, WTF::Function<void(ServiceWorkerGlobalScope&)>&&);
private:
SWContextManager() = default;
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp (226273 => 226274)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -93,10 +93,11 @@
void dispatchFetchEvent(Ref<Client>&& client, ServiceWorkerGlobalScope& globalScope, std::optional<ServiceWorkerClientIdentifier> clientId, ResourceRequest&& request, String&& referrer, FetchOptions&& options)
{
- ASSERT(globalScope.isServiceWorkerGlobalScope());
-
auto requestHeaders = FetchHeaders::create(FetchHeaders::Guard::Immutable, HTTPHeaderMap { request.httpHeaderFields() });
+ bool isNavigation = options.mode == FetchOptions::Mode::Navigate;
+ bool isNonSubresourceRequest = WebCore::isNonSubresourceRequest(options.destination);
+
auto* formData = request.httpBody();
std::optional<FetchBody> body;
if (formData && !formData->isEmpty()) {
@@ -111,7 +112,7 @@
FetchEvent::Init init;
init.request = WTFMove(fetchRequest);
- if (options.mode == FetchOptions::Mode::Navigate) {
+ if (isNavigation) {
// FIXME: Set reservedClientId.
if (clientId)
init.targetClientId = clientId->toString();
@@ -132,10 +133,13 @@
return;
}
client->didNotHandle();
- // FIXME: Handle soft update.
}
globalScope.updateExtendedEventsSet(event.ptr());
+
+ auto& registration = globalScope.registration();
+ if (isNonSubresourceRequest || registration.needsUpdate())
+ registration.softUpdate();
}
} // namespace ServiceWorkerFetch
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h (226273 => 226274)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -39,6 +39,7 @@
class ResourceResponse;
struct ServiceWorkerClientIdentifier;
class ServiceWorkerGlobalScope;
+class ServiceWorkerGlobalScope;
class SharedBuffer;
namespace ServiceWorkerFetch {
Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (226273 => 226274)
--- trunk/Source/WebCore/workers/service/server/SWServer.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -302,7 +302,7 @@
if (!connection)
return;
- connection->startScriptFetchInClient(jobData.identifier(), cachePolicy);
+ connection->startScriptFetchInClient(jobData.identifier(), jobData.registrationKey(), cachePolicy);
}
void SWServer::scriptFetchFinished(Connection& connection, const ServiceWorkerFetchResult& result)
Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (226273 => 226274)
--- trunk/Source/WebCore/workers/service/server/SWServer.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -106,7 +106,7 @@
virtual void rejectJobInClient(const ServiceWorkerJobDataIdentifier&, const ExceptionData&) = 0;
virtual void resolveRegistrationJobInClient(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved) = 0;
virtual void resolveUnregistrationJobInClient(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationKey&, bool registrationResult) = 0;
- virtual void startScriptFetchInClient(const ServiceWorkerJobDataIdentifier&, FetchOptions::Cache) = 0;
+ virtual void startScriptFetchInClient(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationKey&, FetchOptions::Cache) = 0;
struct RegistrationReadyRequest {
SecurityOriginData topOrigin;
Modified: trunk/Source/WebKit/ChangeLog (226273 => 226274)
--- trunk/Source/WebKit/ChangeLog 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebKit/ChangeLog 2017-12-22 21:17:46 UTC (rev 226274)
@@ -1,3 +1,16 @@
+2017-12-22 Chris Dumez <[email protected]>
+
+ [Service Workers] Implement "Soft Update" algorithm
+ https://bugs.webkit.org/show_bug.cgi?id=180702
+ <rdar://problem/36163461>
+
+ Reviewed by Youenn Fablet.
+
+ * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+ (WebKit::WebSWServerConnection::startScriptFetchInClient):
+ * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+ * WebProcess/Storage/WebSWClientConnection.messages.in:
+
2017-12-22 Michael Catanzaro <[email protected]>
[GTK] Duplicated symbols in libjavascriptcoregtk and libwebkit2gtk can cause crashes in production builds
Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp (226273 => 226274)
--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp 2017-12-22 21:17:46 UTC (rev 226274)
@@ -91,9 +91,9 @@
send(Messages::WebSWClientConnection::UnregistrationJobResolvedInServer(jobDataIdentifier, unregistrationResult));
}
-void WebSWServerConnection::startScriptFetchInClient(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, FetchOptions::Cache cachePolicy)
+void WebSWServerConnection::startScriptFetchInClient(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, const ServiceWorkerRegistrationKey& registrationKey, FetchOptions::Cache cachePolicy)
{
- send(Messages::WebSWClientConnection::StartScriptFetchForServer(jobDataIdentifier, cachePolicy));
+ send(Messages::WebSWClientConnection::StartScriptFetchForServer(jobDataIdentifier, registrationKey, cachePolicy));
}
void WebSWServerConnection::updateRegistrationStateInClient(ServiceWorkerRegistrationIdentifier identifier, ServiceWorkerRegistrationState state, const std::optional<ServiceWorkerData>& serviceWorkerData)
Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h (226273 => 226274)
--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h 2017-12-22 21:17:46 UTC (rev 226274)
@@ -74,7 +74,7 @@
void rejectJobInClient(const WebCore::ServiceWorkerJobDataIdentifier&, const WebCore::ExceptionData&) final;
void resolveRegistrationJobInClient(const WebCore::ServiceWorkerJobDataIdentifier&, const WebCore::ServiceWorkerRegistrationData&, WebCore::ShouldNotifyWhenResolved) final;
void resolveUnregistrationJobInClient(const WebCore::ServiceWorkerJobDataIdentifier&, const WebCore::ServiceWorkerRegistrationKey&, bool unregistrationResult) final;
- void startScriptFetchInClient(const WebCore::ServiceWorkerJobDataIdentifier&, WebCore::FetchOptions::Cache) final;
+ void startScriptFetchInClient(const WebCore::ServiceWorkerJobDataIdentifier&, const WebCore::ServiceWorkerRegistrationKey&, WebCore::FetchOptions::Cache) final;
void updateRegistrationStateInClient(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerRegistrationState, const std::optional<WebCore::ServiceWorkerData>&) final;
void updateWorkerStateInClient(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerState) final;
void fireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier) final;
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in (226273 => 226274)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in 2017-12-22 20:43:35 UTC (rev 226273)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in 2017-12-22 21:17:46 UTC (rev 226274)
@@ -27,7 +27,7 @@
JobRejectedInServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, struct WebCore::ExceptionData exception)
RegistrationJobResolvedInServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, struct WebCore::ServiceWorkerRegistrationData registration, enum WebCore::ShouldNotifyWhenResolved shouldNotifyWhenResolved)
UnregistrationJobResolvedInServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, bool unregistrationResult)
- StartScriptFetchForServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, WebCore::FetchOptions::Cache cachePolicy)
+ StartScriptFetchForServer(struct WebCore::ServiceWorkerJobDataIdentifier jobDataIdentifier, WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::FetchOptions::Cache cachePolicy)
UpdateRegistrationState(WebCore::ServiceWorkerRegistrationIdentifier identifier, enum WebCore::ServiceWorkerRegistrationState state, std::optional<WebCore::ServiceWorkerData> serviceWorkerIdentifier)
UpdateWorkerState(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum WebCore::ServiceWorkerState state)
FireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier identifier)