Diff
Modified: trunk/LayoutTests/ChangeLog (225454 => 225455)
--- trunk/LayoutTests/ChangeLog 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/LayoutTests/ChangeLog 2017-12-03 02:32:42 UTC (rev 225455)
@@ -1,3 +1,17 @@
+2017-12-02 Chris Dumez <[email protected]>
+
+ Support serviceWorkerRegistration.update() inside service workers
+ https://bugs.webkit.org/show_bug.cgi?id=180215
+
+ Reviewed by Darin Adler.
+
+ Add layout test coverage and unskip WPT test that no longer times out.
+
+ * TestExpectations:
+ * http/tests/workers/service/resources/self_registration_update-worker.js: Added.
+ * http/tests/workers/service/self_registration_update-expected.txt: Added.
+ * http/tests/workers/service/self_registration_update.html: Added.
+
2017-12-02 Youenn Fablet <[email protected]>
Implement https://w3c.github.io/ServiceWorker/#clients-getall
Modified: trunk/LayoutTests/TestExpectations (225454 => 225455)
--- trunk/LayoutTests/TestExpectations 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/LayoutTests/TestExpectations 2017-12-03 02:32:42 UTC (rev 225455)
@@ -147,7 +147,6 @@
imported/w3c/web-platform-tests/fetch/api/abort/general-serviceworker.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html [ Skip ]
-imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/clients-matchall-on-evaluation.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/detached-context.https.html [ Skip ]
imported/w3c/web-platform-tests/service-workers/service-worker/extendable-event-waituntil.https.html [ Skip ]
Added: trunk/LayoutTests/http/tests/workers/service/resources/self_registration_update-worker.js (0 => 225455)
--- trunk/LayoutTests/http/tests/workers/service/resources/self_registration_update-worker.js (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/self_registration_update-worker.js 2017-12-03 02:32:42 UTC (rev 225455)
@@ -0,0 +1,4 @@
+self.addEventListener("message", (event) => {
+ self.registration.update();
+});
+
Added: trunk/LayoutTests/http/tests/workers/service/self_registration_update-expected.txt (0 => 225455)
--- trunk/LayoutTests/http/tests/workers/service/self_registration_update-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/self_registration_update-expected.txt 2017-12-03 02:32:42 UTC (rev 225455)
@@ -0,0 +1,7 @@
+* Add basic testing for ServiceWorkerGlobalScope.registration.update()
+
+PASS: registration was successfuly updated by the service worker
+PASS: service worker became redundant
+PASS: Old worker is still the registration's active worker
+PASS: New worker should be the registration's waiting worker
+
Added: trunk/LayoutTests/http/tests/workers/service/self_registration_update.html (0 => 225455)
--- trunk/LayoutTests/http/tests/workers/service/self_registration_update.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/self_registration_update.html 2017-12-03 02:32:42 UTC (rev 225455)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+log("* Add basic testing for ServiceWorkerGlobalScope.registration.update()");
+log("");
+
+navigator.serviceWorker.register("resources/self_registration_update-worker.js", { }).then(function(_registration) {
+ registration = _registration;
+ worker = registration.installing;
+
+ waitForState(worker, "activated").then(function() {
+ registration.addEventListener("updatefound", function() {
+ log("PASS: registration was successfuly updated by the service worker");
+ waitForState(worker, "redundant").then(function() {
+ log("PASS: service worker became redundant");
+ if (registration.active === worker)
+ log("PASS: Old worker is still the registration's active worker");
+ else
+ log("FAIL: Old worker is still the registration's active worker");
+
+ if (!self.registration.waiting || self.registration.waiting === worker)
+ log("FAIL: New worker should be the registration's waiting worker");
+ else
+ log("PASS: New worker should be the registration's waiting worker");
+ finishSWTest();
+ });
+ });
+ worker.postMessage("update");
+ });
+});
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (225454 => 225455)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2017-12-03 02:32:42 UTC (rev 225455)
@@ -1,3 +1,19 @@
+2017-12-02 Chris Dumez <[email protected]>
+
+ Support serviceWorkerRegistration.update() inside service workers
+ https://bugs.webkit.org/show_bug.cgi?id=180215
+
+ Reviewed by Darin Adler.
+
+ Rebaseline WPT test that no longer times out. The test still fails even
+ though we support update(). The issue is that the second frame load
+ uses the new worker (because of the update()) instead of the old one.
+ The test seems to expect that the new service worker is still in
+ waiting state at the point the second frame is loaded. However, for us
+ it is already activated.
+
+ * web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https-expected.txt:
+
2017-12-02 Youenn Fablet <[email protected]>
Implement https://w3c.github.io/ServiceWorker/#clients-getall
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https-expected.txt (225454 => 225455)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https-expected.txt 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https-expected.txt 2017-12-03 02:32:42 UTC (rev 225455)
@@ -1,6 +1,4 @@
-Harness Error (TIMEOUT), message = null
+FAIL Update a registration on ServiceWorkerGlobalScope assert_equals: events seen by the worker expected "updatefound,activate,fetch,message,updatefound,fetch" but got "updatefound,activate,fetch"
-TIMEOUT Update a registration on ServiceWorkerGlobalScope Test timed out
-
Modified: trunk/Source/WebCore/ChangeLog (225454 => 225455)
--- trunk/Source/WebCore/ChangeLog 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/ChangeLog 2017-12-03 02:32:42 UTC (rev 225455)
@@ -1,3 +1,59 @@
+2017-12-02 Chris Dumez <[email protected]>
+
+ Support serviceWorkerRegistration.update() inside service workers
+ https://bugs.webkit.org/show_bug.cgi?id=180215
+
+ Reviewed by Darin Adler.
+
+ Support serviceWorkerRegistration.update() inside service workers. The code paths
+ for job scheduling and resolution have been made thread safe by hopping to the right
+ thread when necessary. In particular, ServiceWorkerContainer always makes sure to to
+ a callOnMainThread() before calling methods on the SWClientConnection. Also, the
+ SWClientConnection relies on a new postTaskTo() method before calling methods on the
+ job.
+
+ Test: http/tests/workers/service/self_registration_update.html
+
+ * workers/service/SWClientConnection.cpp:
+ (WebCore::SWClientConnection::scheduleJob):
+ (WebCore::SWClientConnection::finishedFetchingScript):
+ (WebCore::SWClientConnection::failedFetchingScript):
+ (WebCore::SWClientConnection::jobRejectedInServer):
+ (WebCore::SWClientConnection::registrationJobResolvedInServer):
+ (WebCore::SWClientConnection::unregistrationJobResolvedInServer):
+ (WebCore::SWClientConnection::startScriptFetchForServer):
+ (WebCore::SWClientConnection::postMessageToServiceWorkerClient):
+ (WebCore::SWClientConnection::updateRegistrationState):
+ (WebCore::SWClientConnection::updateWorkerState):
+ (WebCore::SWClientConnection::fireUpdateFoundEvent):
+ (WebCore::SWClientConnection::notifyClientsOfControllerChange):
+ (WebCore::SWClientConnection::clearPendingJobs):
+ (WebCore::SWClientConnection::postTaskTo):
+ * workers/service/SWClientConnection.h:
+ * workers/service/ServiceWorkerContainer.cpp:
+ (WebCore::ServiceWorkerContainer::scheduleJob):
+ (WebCore::ServiceWorkerContainer::jobFailedWithException):
+ (WebCore::ServiceWorkerContainer::scheduleTaskToFireUpdateFoundEvent):
+ (WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
+ (WebCore::ServiceWorkerContainer::jobResolvedWithUnregistrationResult):
+ (WebCore::ServiceWorkerContainer::startScriptFetchForJob):
+ (WebCore::ServiceWorkerContainer::jobFinishedLoadingScript):
+ (WebCore::ServiceWorkerContainer::jobFailedLoadingScript):
+ (WebCore::ServiceWorkerContainer::jobDidFinish):
+ (WebCore::ServiceWorkerContainer::addRegistration):
+ (WebCore::ServiceWorkerContainer::removeRegistration):
+ (WebCore::ServiceWorkerContainer::scheduleTaskToFireControllerChangeEvent):
+ (WebCore::ServiceWorkerContainer::contextIdentifier):
+ * workers/service/ServiceWorkerContainer.h:
+ * workers/service/ServiceWorkerJob.cpp:
+ (WebCore::ServiceWorkerJob::ServiceWorkerJob):
+ * workers/service/ServiceWorkerJob.h:
+ (WebCore::ServiceWorkerJob::contextIdentifier):
+ * workers/service/ServiceWorkerJobClient.h:
+ * workers/service/ServiceWorkerRegistration.cpp:
+ (WebCore::ServiceWorkerRegistration::update):
+ * workers/service/ServiceWorkerTypes.h:
+
2017-12-02 Simon Fraser <[email protected]>
Make IOSurface::Locker and use it in ImageBufferDataCG
Modified: trunk/Source/WebCore/workers/service/SWClientConnection.cpp (225454 => 225455)
--- trunk/Source/WebCore/workers/service/SWClientConnection.cpp 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/SWClientConnection.cpp 2017-12-03 02:32:42 UTC (rev 225455)
@@ -47,6 +47,8 @@
void SWClientConnection::scheduleJob(ServiceWorkerJob& job)
{
+ ASSERT(isMainThread());
+
auto addResult = m_scheduledJobs.add(job.identifier(), &job);
ASSERT_UNUSED(addResult, addResult.isNewEntry);
@@ -55,6 +57,7 @@
void SWClientConnection::finishedFetchingScript(ServiceWorkerJob& job, const String& script)
{
+ ASSERT(isMainThread());
ASSERT(m_scheduledJobs.get(job.identifier()) == &job);
finishFetchingScriptInServer({ job.data().identifier(), job.data().registrationKey(), script, { } });
@@ -62,6 +65,7 @@
void SWClientConnection::failedFetchingScript(ServiceWorkerJob& job, const ResourceError& error)
{
+ ASSERT(isMainThread());
ASSERT(m_scheduledJobs.get(job.identifier()) == &job);
finishFetchingScriptInServer({ job.data().identifier(), job.data().registrationKey(), { }, error });
@@ -69,6 +73,8 @@
void SWClientConnection::jobRejectedInServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, const ExceptionData& exceptionData)
{
+ ASSERT(isMainThread());
+
auto job = m_scheduledJobs.take(jobDataIdentifier.jobIdentifier);
if (!job) {
LOG_ERROR("Job %s rejected from server, but was not found", jobDataIdentifier.loggingString().utf8().data());
@@ -75,11 +81,15 @@
return;
}
- job->failedWithException(exceptionData.toException());
+ postTaskTo(job->contextIdentifier(), [job, exceptionData = exceptionData.isolatedCopy()] {
+ job->failedWithException(exceptionData.toException());
+ });
}
void SWClientConnection::registrationJobResolvedInServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, ServiceWorkerRegistrationData&& registrationData, ShouldNotifyWhenResolved shouldNotifyWhenResolved)
{
+ ASSERT(isMainThread());
+
auto job = m_scheduledJobs.take(jobDataIdentifier.jobIdentifier);
if (!job) {
LOG_ERROR("Job %s resolved in server, but was not found", jobDataIdentifier.loggingString().utf8().data());
@@ -86,12 +96,15 @@
return;
}
- auto key = registrationData.key;
- job->resolvedWithRegistration(WTFMove(registrationData), shouldNotifyWhenResolved);
+ postTaskTo(job->contextIdentifier(), [job, registrationData = registrationData.isolatedCopy(), shouldNotifyWhenResolved]() mutable {
+ job->resolvedWithRegistration(WTFMove(registrationData), shouldNotifyWhenResolved);
+ });
}
void SWClientConnection::unregistrationJobResolvedInServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, bool unregistrationResult)
{
+ ASSERT(isMainThread());
+
auto job = m_scheduledJobs.take(jobDataIdentifier.jobIdentifier);
if (!job) {
LOG_ERROR("Job %s resolved in server, but was not found", jobDataIdentifier.loggingString().utf8().data());
@@ -98,11 +111,15 @@
return;
}
- job->resolvedWithUnregistrationResult(unregistrationResult);
+ postTaskTo(job->contextIdentifier(), [job, unregistrationResult] {
+ job->resolvedWithUnregistrationResult(unregistrationResult);
+ });
}
void SWClientConnection::startScriptFetchForServer(const ServiceWorkerJobDataIdentifier& jobDataIdentifier)
{
+ ASSERT(isMainThread());
+
auto job = m_scheduledJobs.get(jobDataIdentifier.jobIdentifier);
if (!job) {
LOG_ERROR("Job %s instructed to start fetch from server, but job was not found", jobDataIdentifier.loggingString().utf8().data());
@@ -114,11 +131,15 @@
return;
}
- job->startScriptFetch();
+ postTaskTo(job->contextIdentifier(), [job] {
+ job->startScriptFetch();
+ });
}
void SWClientConnection::postMessageToServiceWorkerClient(DocumentIdentifier destinationContextIdentifier, Ref<SerializedScriptValue>&& message, ServiceWorkerData&& sourceData, const String& sourceOrigin)
{
+ ASSERT(isMainThread());
+
// FIXME: destinationContextIdentifier can only identify a Document at the moment.
auto* destinationDocument = Document::allDocumentsMap().get(destinationContextIdentifier);
if (!destinationDocument)
@@ -137,6 +158,8 @@
void SWClientConnection::updateRegistrationState(ServiceWorkerRegistrationIdentifier identifier, ServiceWorkerRegistrationState state, const std::optional<ServiceWorkerData>& serviceWorkerData)
{
+ ASSERT(isMainThread());
+
SWContextManager::singleton().forEachServiceWorkerThread([identifier, state, &serviceWorkerData] (auto& workerThread) {
workerThread.thread().runLoop().postTask([identifier, state, serviceWorkerData = crossThreadCopy(serviceWorkerData)](ScriptExecutionContext& context) mutable {
if (auto* container = context.serviceWorkerContainer())
@@ -152,6 +175,8 @@
void SWClientConnection::updateWorkerState(ServiceWorkerIdentifier identifier, ServiceWorkerState state)
{
+ ASSERT(isMainThread());
+
SWContextManager::singleton().forEachServiceWorkerThread([identifier, state] (auto& workerThread) {
workerThread.thread().runLoop().postTask([identifier, state](ScriptExecutionContext& context) {
if (auto* serviceWorker = context.serviceWorker(identifier))
@@ -167,6 +192,8 @@
void SWClientConnection::fireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier identifier)
{
+ ASSERT(isMainThread());
+
SWContextManager::singleton().forEachServiceWorkerThread([identifier] (auto& workerThread) {
workerThread.thread().runLoop().postTask([identifier](ScriptExecutionContext& context) {
if (auto* container = context.serviceWorkerContainer())
@@ -182,6 +209,7 @@
void SWClientConnection::notifyClientsOfControllerChange(const HashSet<DocumentIdentifier>& contextIdentifiers, ServiceWorkerData&& newController)
{
+ ASSERT(isMainThread());
ASSERT(!contextIdentifiers.isEmpty());
for (auto& clientIdentifier : contextIdentifiers) {
@@ -200,11 +228,34 @@
void SWClientConnection::clearPendingJobs()
{
+ ASSERT(isMainThread());
+
auto jobs = WTFMove(m_scheduledJobs);
- for (auto& job : jobs.values())
- job->failedWithException(Exception { TypeError, ASCIILiteral("Internal error") });
+ for (auto& job : jobs.values()) {
+ postTaskTo(job->contextIdentifier(), [job] {
+ job->failedWithException(Exception { TypeError, ASCIILiteral("Internal error") });
+ });
+ }
}
+void SWClientConnection::postTaskTo(const DocumentOrWorkerIdentifier& contextIdentifier, WTF::Function<void()>&& task)
+{
+ ASSERT(isMainThread());
+
+ switchOn(contextIdentifier, [&](DocumentIdentifier identifier) {
+ auto* document = Document::allDocumentsMap().get(identifier);
+ if (!document)
+ return;
+ document->postTask([task = WTFMove(task)](ScriptExecutionContext&) {
+ task();
+ });
+ }, [&](ServiceWorkerIdentifier identifier) {
+ SWContextManager::singleton().postTaskToServiceWorker(identifier, [task = WTFMove(task)](ServiceWorkerGlobalScope&) {
+ task();
+ });
+ });
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/SWClientConnection.h (225454 => 225455)
--- trunk/Source/WebCore/workers/service/SWClientConnection.h 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/SWClientConnection.h 2017-12-03 02:32:42 UTC (rev 225455)
@@ -95,6 +95,7 @@
WEBCORE_EXPORT void notifyClientsOfControllerChange(const HashSet<DocumentIdentifier>& contextIdentifiers, ServiceWorkerData&& newController);
WEBCORE_EXPORT void clearPendingJobs();
+ WEBCORE_EXPORT void postTaskTo(const DocumentOrWorkerIdentifier&, WTF::Function<void()>&&);
private:
virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp (225454 => 225455)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-12-03 02:32:42 UTC (rev 225455)
@@ -28,6 +28,7 @@
#if ENABLE(SERVICE_WORKER)
+#include "Document.h"
#include "Event.h"
#include "EventNames.h"
#include "Exception.h"
@@ -40,9 +41,11 @@
#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"
#include "ServiceWorker.h"
+#include "ServiceWorkerGlobalScope.h"
#include "ServiceWorkerJob.h"
#include "ServiceWorkerJobData.h"
#include "ServiceWorkerProvider.h"
+#include "ServiceWorkerThread.h"
#include "URL.h"
#include <wtf/RunLoop.h>
#include <wtf/Scope.h>
@@ -196,15 +199,20 @@
void ServiceWorkerContainer::scheduleJob(Ref<ServiceWorkerJob>&& job)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
ASSERT(m_swConnection);
setPendingActivity(this);
- ServiceWorkerJob& rawJob = job.get();
- auto result = m_jobMap.add(rawJob.identifier(), WTFMove(job));
+ auto result = m_jobMap.add(job->identifier(), job.copyRef());
ASSERT_UNUSED(result, result.isNewEntry);
- m_swConnection->scheduleJob(rawJob);
+ callOnMainThread([connection = m_swConnection, job = WTFMove(job)] {
+ connection->scheduleJob(job);
+ });
}
void ServiceWorkerContainer::getRegistration(const String& clientURL, Ref<DeferredPromise>&& promise)
@@ -293,6 +301,10 @@
void ServiceWorkerContainer::jobFailedWithException(ServiceWorkerJob& job, const Exception& exception)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
if (auto* context = scriptExecutionContext()) {
context->postTask([job = makeRef(job), exception](ScriptExecutionContext&) {
job->promise().reject(exception);
@@ -303,6 +315,10 @@
void ServiceWorkerContainer::scheduleTaskToFireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier identifier)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
if (auto* registration = m_registrations.get(identifier))
registration->scheduleTaskToFireUpdateFoundEvent();
}
@@ -309,6 +325,10 @@
void ServiceWorkerContainer::jobResolvedWithRegistration(ServiceWorkerJob& job, ServiceWorkerRegistrationData&& data, ShouldNotifyWhenResolved shouldNotifyWhenResolved)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
auto guard = WTF::makeScopeExit([this, &job] {
jobDidFinish(job);
});
@@ -345,6 +365,10 @@
void ServiceWorkerContainer::jobResolvedWithUnregistrationResult(ServiceWorkerJob& job, bool unregistrationResult)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
auto guard = WTF::makeScopeExit([this, &job] {
jobDidFinish(job);
});
@@ -362,12 +386,18 @@
void ServiceWorkerContainer::startScriptFetchForJob(ServiceWorkerJob& job)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
LOG(ServiceWorker, "SeviceWorkerContainer %p starting script fetch for job %s", this, job.identifier().loggingString().utf8().data());
auto* context = scriptExecutionContext();
if (!context) {
LOG_ERROR("ServiceWorkerContainer::jobResolvedWithRegistration called but the container's ScriptExecutionContext is gone");
- m_swConnection->failedFetchingScript(job, { errorDomainWebKitInternal, 0, job.data().scriptURL, ASCIILiteral("Attempt to fetch service worker script with no ScriptExecutionContext") });
+ 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") });
+ });
jobDidFinish(job);
return;
}
@@ -377,23 +407,39 @@
void ServiceWorkerContainer::jobFinishedLoadingScript(ServiceWorkerJob& job, const String& script)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
LOG(ServiceWorker, "SeviceWorkerContainer %p finished fetching script for job %s", this, job.identifier().loggingString().utf8().data());
- m_swConnection->finishedFetchingScript(job, script);
+ callOnMainThread([connection = m_swConnection, job = makeRef(job), script = script.isolatedCopy()] {
+ connection->finishedFetchingScript(job, script);
+ });
}
void ServiceWorkerContainer::jobFailedLoadingScript(ServiceWorkerJob& job, const ResourceError& error, std::optional<Exception>&& exception)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
LOG(ServiceWorker, "SeviceWorkerContainer %p failed fetching script for job %s", this, job.identifier().loggingString().utf8().data());
if (exception)
job.promise().reject(*exception);
- m_swConnection->failedFetchingScript(job, error);
+ callOnMainThread([connection = m_swConnection, job = makeRef(job), error = error.isolatedCopy()] {
+ connection->failedFetchingScript(job, error);
+ });
}
void ServiceWorkerContainer::jobDidFinish(ServiceWorkerJob& job)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
auto taken = m_jobMap.take(job.identifier());
ASSERT_UNUSED(taken, !taken || taken->ptr() == &job);
@@ -429,6 +475,10 @@
void ServiceWorkerContainer::addRegistration(ServiceWorkerRegistration& registration)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
ensureSWClientConnection().addServiceWorkerRegistrationInServer(registration.identifier());
m_registrations.add(registration.identifier(), ®istration);
}
@@ -435,6 +485,10 @@
void ServiceWorkerContainer::removeRegistration(ServiceWorkerRegistration& registration)
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
m_swConnection->removeServiceWorkerRegistrationInServer(registration.identifier());
m_registrations.remove(registration.identifier());
}
@@ -441,6 +495,10 @@
void ServiceWorkerContainer::scheduleTaskToFireControllerChangeEvent()
{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
if (m_isStopped)
return;
@@ -458,6 +516,18 @@
removeAllEventListeners();
}
+DocumentOrWorkerIdentifier ServiceWorkerContainer::contextIdentifier()
+{
+#ifndef NDEBUG
+ ASSERT(m_creationThread == currentThread());
+#endif
+
+ ASSERT(scriptExecutionContext());
+ if (is<ServiceWorkerGlobalScope>(*scriptExecutionContext()))
+ return downcast<ServiceWorkerGlobalScope>(*scriptExecutionContext()).thread().identifier();
+ return downcast<Document>(*scriptExecutionContext()).identifier();
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h (225454 => 225455)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-12-03 02:32:42 UTC (rev 225455)
@@ -96,6 +96,8 @@
void jobDidFinish(ServiceWorkerJob&);
SWServerConnectionIdentifier connectionIdentifier() final;
+ DocumentOrWorkerIdentifier contextIdentifier() final;
+
SWClientConnection& ensureSWClientConnection();
const char* activeDOMObjectName() const final;
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp (225454 => 225455)
--- trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp 2017-12-03 02:32:42 UTC (rev 225455)
@@ -41,6 +41,7 @@
: m_client(client)
, m_jobData(WTFMove(jobData))
, m_promise(WTFMove(promise))
+ , m_contextIdentifier(client.contextIdentifier())
{
}
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerJob.h (225454 => 225455)
--- trunk/Source/WebCore/workers/service/ServiceWorkerJob.h 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerJob.h 2017-12-03 02:32:42 UTC (rev 225455)
@@ -68,6 +68,8 @@
void fetchScriptWithContext(ScriptExecutionContext&);
+ const DocumentOrWorkerIdentifier& contextIdentifier() { return m_contextIdentifier; }
+
private:
ServiceWorkerJob(ServiceWorkerJobClient&, Ref<DeferredPromise>&&, ServiceWorkerJobData&&);
@@ -83,7 +85,7 @@
bool m_completed { false };
- Ref<RunLoop> m_runLoop { RunLoop::current() };
+ DocumentOrWorkerIdentifier m_contextIdentifier;
RefPtr<WorkerScriptLoader> m_scriptLoader;
ResourceResponse m_lastResponse;
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerJobClient.h (225454 => 225455)
--- trunk/Source/WebCore/workers/service/ServiceWorkerJobClient.h 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerJobClient.h 2017-12-03 02:32:42 UTC (rev 225455)
@@ -41,6 +41,8 @@
public:
virtual ~ServiceWorkerJobClient() = default;
+ virtual DocumentOrWorkerIdentifier contextIdentifier() = 0;
+
virtual void jobFailedWithException(ServiceWorkerJob&, const Exception&) = 0;
virtual void jobResolvedWithRegistration(ServiceWorkerJob&, ServiceWorkerRegistrationData&&, ShouldNotifyWhenResolved) = 0;
virtual void jobResolvedWithUnregistrationResult(ServiceWorkerJob&, bool unregistrationResult) = 0;
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp (225454 => 225455)
--- trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp 2017-12-03 02:32:42 UTC (rev 225455)
@@ -121,18 +121,6 @@
return;
}
- // FIXME: Add support in workers.
- if (!is<Document>(*context)) {
- promise->reject(Exception { NotSupportedError, ASCIILiteral("serviceWorkerRegistration.update() is not yet supported in workers") });
- return;
- }
-
- auto* container = context->serviceWorkerContainer();
- if (!container) {
- promise->reject(Exception(InvalidStateError));
- return;
- }
-
auto* newestWorker = getNewestWorker();
if (!newestWorker) {
promise->reject(Exception(InvalidStateError, ASCIILiteral("newestWorker is null")));
@@ -140,7 +128,7 @@
}
// FIXME: Support worker types.
- container->updateRegistration(m_registrationData.scopeURL, newestWorker->scriptURL(), WorkerType::Classic, WTFMove(promise));
+ m_container->updateRegistration(m_registrationData.scopeURL, newestWorker->scriptURL(), WorkerType::Classic, WTFMove(promise));
}
void ServiceWorkerRegistration::unregister(Ref<DeferredPromise>&& promise)
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerTypes.h (225454 => 225455)
--- trunk/Source/WebCore/workers/service/ServiceWorkerTypes.h 2017-12-02 23:11:12 UTC (rev 225454)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerTypes.h 2017-12-03 02:32:42 UTC (rev 225455)
@@ -27,8 +27,11 @@
#if ENABLE(SERVICE_WORKER)
+#include "DocumentIdentifier.h"
+#include "ServiceWorkerIdentifier.h"
#include <wtf/EnumTraits.h>
#include <wtf/ObjectIdentifier.h>
+#include <wtf/Variant.h>
namespace WebCore {
@@ -67,6 +70,8 @@
enum SWServerConnectionIdentifierType { };
using SWServerConnectionIdentifier = ObjectIdentifier<SWServerConnectionIdentifierType>;
+using DocumentOrWorkerIdentifier = Variant<DocumentIdentifier, ServiceWorkerIdentifier>;
+
} // namespace WebCore
namespace WTF {