Split JobQueue logic out of SWServerRegistration
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Nov 2017 22:32:42 +0000 (22:32 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Nov 2017 22:32:42 +0000 (22:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179126

Reviewed by Brady Eidson.

Split JobQueue logic out of SWServerRegistration and into a SWServerJobQueue class to match the Service Workers
specification more closely.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
* workers/service/ServiceWorkerRegistrationData.cpp:
(WebCore::ServiceWorkerRegistrationData::isolatedCopy const):
* workers/service/ServiceWorkerRegistrationData.h:
(WebCore::ServiceWorkerRegistrationData::encode const):
(WebCore::ServiceWorkerRegistrationData::decode):
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::~SWServer):
(WebCore::SWServer::getRegistration):
(WebCore::SWServer::addRegistration):
(WebCore::SWServer::removeRegistration):
(WebCore::SWServer::Connection::scriptContextStarted):
(WebCore::SWServer::scheduleJob):
(WebCore::SWServer::scriptFetchFinished):
(WebCore::SWServer::scriptContextFailedToStart):
(WebCore::SWServer::scriptContextStarted):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerJobQueue.cpp: Added.
(WebCore::SWServerJobQueue::SWServerJobQueue):
(WebCore::SWServerJobQueue::~SWServerJobQueue):
(WebCore::SWServerJobQueue::enqueueJob):
(WebCore::SWServerJobQueue::scriptFetchFinished):
(WebCore::SWServerJobQueue::scriptContextFailedToStart):
(WebCore::SWServerJobQueue::scriptContextStarted):
(WebCore::SWServerJobQueue::startNextJob):
(WebCore::SWServerJobQueue::runRegisterJob):
(WebCore::SWServerJobQueue::runUnregisterJob):
(WebCore::SWServerJobQueue::runUpdateJob):
(WebCore::SWServerJobQueue::rejectWithExceptionOnMainThread):
(WebCore::SWServerJobQueue::resolveWithRegistrationOnMainThread):
(WebCore::SWServerJobQueue::resolveCurrentRegistrationJobOnMainThead):
(WebCore::SWServerJobQueue::resolveWithUnregistrationResultOnMainThread):
(WebCore::SWServerJobQueue::startScriptFetchFromMainThread):
(WebCore::SWServerJobQueue::rejectCurrentJob):
(WebCore::SWServerJobQueue::resolveCurrentRegistrationJob):
(WebCore::SWServerJobQueue::resolveCurrentUnregistrationJob):
(WebCore::SWServerJobQueue::startScriptFetchForCurrentJob):
(WebCore::SWServerJobQueue::finishCurrentJob):
* workers/service/server/SWServerJobQueue.h: Added.
* workers/service/server/SWServerRegistration.cpp:
(WebCore::SWServerRegistration::SWServerRegistration):
(WebCore::SWServerRegistration::~SWServerRegistration):
(WebCore::SWServerRegistration::data const):
* workers/service/server/SWServerRegistration.h:
(WebCore::SWServerRegistration::key const):
(WebCore::SWServerRegistration::isUninstalling const):
(WebCore::SWServerRegistration::setIsUninstalling):
(WebCore::SWServerRegistration::setLastUpdateTime):
(WebCore::SWServerRegistration::updateViaCache const):
(WebCore::SWServerRegistration::setActiveServiceWorkerIdentifier):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224301 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerRegistrationData.cpp
Source/WebCore/workers/service/ServiceWorkerRegistrationData.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerJobQueue.cpp [new file with mode: 0644]
Source/WebCore/workers/service/server/SWServerJobQueue.h [new file with mode: 0644]
Source/WebCore/workers/service/server/SWServerRegistration.cpp
Source/WebCore/workers/service/server/SWServerRegistration.h

index 0c4e376..211f0b7 100644 (file)
@@ -1,3 +1,67 @@
+2017-11-01  Chris Dumez  <cdumez@apple.com>
+
+        Split JobQueue logic out of SWServerRegistration
+        https://bugs.webkit.org/show_bug.cgi?id=179126
+
+        Reviewed by Brady Eidson.
+
+        Split JobQueue logic out of SWServerRegistration and into a SWServerJobQueue class to match the Service Workers
+        specification more closely.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
+        * workers/service/ServiceWorkerRegistrationData.cpp:
+        (WebCore::ServiceWorkerRegistrationData::isolatedCopy const):
+        * workers/service/ServiceWorkerRegistrationData.h:
+        (WebCore::ServiceWorkerRegistrationData::encode const):
+        (WebCore::ServiceWorkerRegistrationData::decode):
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::~SWServer):
+        (WebCore::SWServer::getRegistration):
+        (WebCore::SWServer::addRegistration):
+        (WebCore::SWServer::removeRegistration):
+        (WebCore::SWServer::Connection::scriptContextStarted):
+        (WebCore::SWServer::scheduleJob):
+        (WebCore::SWServer::scriptFetchFinished):
+        (WebCore::SWServer::scriptContextFailedToStart):
+        (WebCore::SWServer::scriptContextStarted):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerJobQueue.cpp: Added.
+        (WebCore::SWServerJobQueue::SWServerJobQueue):
+        (WebCore::SWServerJobQueue::~SWServerJobQueue):
+        (WebCore::SWServerJobQueue::enqueueJob):
+        (WebCore::SWServerJobQueue::scriptFetchFinished):
+        (WebCore::SWServerJobQueue::scriptContextFailedToStart):
+        (WebCore::SWServerJobQueue::scriptContextStarted):
+        (WebCore::SWServerJobQueue::startNextJob):
+        (WebCore::SWServerJobQueue::runRegisterJob):
+        (WebCore::SWServerJobQueue::runUnregisterJob):
+        (WebCore::SWServerJobQueue::runUpdateJob):
+        (WebCore::SWServerJobQueue::rejectWithExceptionOnMainThread):
+        (WebCore::SWServerJobQueue::resolveWithRegistrationOnMainThread):
+        (WebCore::SWServerJobQueue::resolveCurrentRegistrationJobOnMainThead):
+        (WebCore::SWServerJobQueue::resolveWithUnregistrationResultOnMainThread):
+        (WebCore::SWServerJobQueue::startScriptFetchFromMainThread):
+        (WebCore::SWServerJobQueue::rejectCurrentJob):
+        (WebCore::SWServerJobQueue::resolveCurrentRegistrationJob):
+        (WebCore::SWServerJobQueue::resolveCurrentUnregistrationJob):
+        (WebCore::SWServerJobQueue::startScriptFetchForCurrentJob):
+        (WebCore::SWServerJobQueue::finishCurrentJob):
+        * workers/service/server/SWServerJobQueue.h: Added.
+        * workers/service/server/SWServerRegistration.cpp:
+        (WebCore::SWServerRegistration::SWServerRegistration):
+        (WebCore::SWServerRegistration::~SWServerRegistration):
+        (WebCore::SWServerRegistration::data const):
+        * workers/service/server/SWServerRegistration.h:
+        (WebCore::SWServerRegistration::key const):
+        (WebCore::SWServerRegistration::isUninstalling const):
+        (WebCore::SWServerRegistration::setIsUninstalling):
+        (WebCore::SWServerRegistration::setLastUpdateTime):
+        (WebCore::SWServerRegistration::updateViaCache const):
+        (WebCore::SWServerRegistration::setActiveServiceWorkerIdentifier):
+
 2017-11-01  Daniel Bates  <dabates@apple.com>
 
         XMLHttpRequest should not sniff content encoding
index c76f78b..c2a4033 100644 (file)
@@ -2174,6 +2174,7 @@ workers/service/context/SWContextManager.cpp
 
 workers/service/server/SWClientConnection.cpp
 workers/service/server/SWServer.cpp
+workers/service/server/SWServerJobQueue.cpp
 workers/service/server/SWServerRegistration.cpp
 workers/service/server/SWServerWorker.cpp
 
index 078a3ab..067aaee 100644 (file)
                830784B21C52EE2C00104D1D /* XMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 830784B11C52EE1900104D1D /* XMLDocument.h */; settings = {ATTRIBUTES = (Private, ); }; };
                830A36BD1DAC5FAD006D7D09 /* JSMouseEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 830A36BB1DAC5FA7006D7D09 /* JSMouseEventInit.h */; };
                83102B271F9EADD900E404B9 /* JSExtendableMessageEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 83102B231F9EADC200E404B9 /* JSExtendableMessageEvent.h */; };
+               8311C0031FAA2E9500E3C8E5 /* SWServerJobQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 8311C0021FAA2E8900E3C8E5 /* SWServerJobQueue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                83120C711C56F3FB001CB112 /* HTMLDataElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B86A71C56E83A00F3F0E3 /* HTMLDataElement.h */; };
                8321507E1F27EA1B0095B136 /* NavigatorBeacon.h in Headers */ = {isa = PBXBuildFile; fileRef = 8321507B1F27EA150095B136 /* NavigatorBeacon.h */; };
                832B843419D8E55100B26055 /* SVGAnimateElementBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 832B843319D8E55100B26055 /* SVGAnimateElementBase.h */; };
                830A36BB1DAC5FA7006D7D09 /* JSMouseEventInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMouseEventInit.h; sourceTree = "<group>"; };
                83102B231F9EADC200E404B9 /* JSExtendableMessageEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSExtendableMessageEvent.h; sourceTree = "<group>"; };
                83102B251F9EADC200E404B9 /* JSExtendableMessageEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSExtendableMessageEvent.cpp; sourceTree = "<group>"; };
+               8311C0001FAA2E8900E3C8E5 /* SWServerJobQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SWServerJobQueue.cpp; sourceTree = "<group>"; };
+               8311C0021FAA2E8900E3C8E5 /* SWServerJobQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWServerJobQueue.h; sourceTree = "<group>"; };
                831C46C31F9EE5E000EBD450 /* JSExtendableMessageEventCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSExtendableMessageEventCustom.cpp; sourceTree = "<group>"; };
                831D1F291C56ECA000F5F6C0 /* HTMLDataElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLDataElement.cpp; sourceTree = "<group>"; };
                8321507A1F27EA150095B136 /* NavigatorBeacon.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NavigatorBeacon.cpp; sourceTree = "<group>"; };
                                517A52FF1F478CCE00DCDC0A /* SWClientConnection.h */,
                                517A52EF1F47535900DCDC0A /* SWServer.cpp */,
                                517A52EE1F47535900DCDC0A /* SWServer.h */,
+                               8311C0001FAA2E8900E3C8E5 /* SWServerJobQueue.cpp */,
+                               8311C0021FAA2E8900E3C8E5 /* SWServerJobQueue.h */,
                                51F645951F4A686100B54DED /* SWServerRegistration.cpp */,
                                51F645941F4A684F00B54DED /* SWServerRegistration.h */,
                                517A53431F50C16100DCDC0A /* SWServerWorker.cpp */,
                                517A531D1F4B53B100DCDC0A /* SWClientConnection.h in Headers */,
                                46658DC91FA24B8700F7DD54 /* SWContextManager.h in Headers */,
                                517A52F01F47535B00DCDC0A /* SWServer.h in Headers */,
+                               8311C0031FAA2E9500E3C8E5 /* SWServerJobQueue.h in Headers */,
                                51F645971F4A686F00B54DED /* SWServerRegistration.h in Headers */,
                                517A53461F50C17F00DCDC0A /* SWServerWorker.h in Headers */,
                                E180811716FCF9CB00B80D07 /* SynchronousLoaderClient.h in Headers */,
index cc77e88..4762918 100644 (file)
@@ -244,8 +244,8 @@ void ServiceWorkerContainer::jobResolvedWithRegistration(ServiceWorkerJob& job,
 
     // FIXME: Implement proper selection of service workers.
     auto* activeServiceWorker = context->activeServiceWorker();
-    if (!activeServiceWorker || activeServiceWorker->identifier() != data.identifier) {
-        context->setActiveServiceWorker(ServiceWorker::create(*context, data.identifier, data.scriptURL));
+    if (!activeServiceWorker || activeServiceWorker->identifier() != data.activeServiceWorkerIdentifier) {
+        context->setActiveServiceWorker(ServiceWorker::create(*context, data.activeServiceWorkerIdentifier, data.scriptURL));
         activeServiceWorker = context->activeServiceWorker();
     }
 
index 6c67aa6..68794d4 100644 (file)
@@ -35,6 +35,7 @@ ServiceWorkerRegistrationData ServiceWorkerRegistrationData::isolatedCopy() cons
     return {
         key.isolatedCopy(),
         identifier,
+        activeServiceWorkerIdentifier,
         scopeURL.isolatedCopy(),
         scriptURL.isolatedCopy(),
         updateViaCache
index 74c95f1..dc55f66 100644 (file)
@@ -36,6 +36,7 @@ enum class ServiceWorkerUpdateViaCache;
 struct ServiceWorkerRegistrationData {
     ServiceWorkerRegistrationKey key;
     uint64_t identifier;
+    uint64_t activeServiceWorkerIdentifier; // FIXME: This should not be part of registrationData.
     URL scopeURL;
     URL scriptURL;
     ServiceWorkerUpdateViaCache updateViaCache;
@@ -50,7 +51,7 @@ struct ServiceWorkerRegistrationData {
 template<class Encoder>
 void ServiceWorkerRegistrationData::encode(Encoder& encoder) const
 {
-    encoder << key << identifier << scopeURL << scriptURL << updateViaCache;
+    encoder << key << identifier << activeServiceWorkerIdentifier << scopeURL << scriptURL << updateViaCache;
 }
 
 template<class Decoder>
@@ -66,6 +67,11 @@ std::optional<ServiceWorkerRegistrationData> ServiceWorkerRegistrationData::deco
     if (!identifier)
         return std::nullopt;
 
+    std::optional<uint64_t> activeServiceWorkerIdentifier;
+    decoder >> activeServiceWorkerIdentifier;
+    if (!activeServiceWorkerIdentifier)
+        return std::nullopt;
+
     std::optional<URL> scopeURL;
     decoder >> scopeURL;
     if (!scopeURL)
@@ -81,7 +87,7 @@ std::optional<ServiceWorkerRegistrationData> ServiceWorkerRegistrationData::deco
     if (!updateViaCache)
         return std::nullopt;
 
-    return { { WTFMove(*key), WTFMove(*identifier), WTFMove(*scopeURL), WTFMove(*scriptURL), WTFMove(*updateViaCache) } };
+    return { { WTFMove(*key), WTFMove(*identifier), WTFMove(*activeServiceWorkerIdentifier), WTFMove(*scopeURL), WTFMove(*scriptURL), WTFMove(*updateViaCache) } };
 }
 
 } // namespace WTF
index ef27875..e6f777d 100644 (file)
@@ -31,6 +31,7 @@
 #include "ExceptionCode.h"
 #include "ExceptionData.h"
 #include "Logging.h"
+#include "SWServerJobQueue.h"
 #include "SWServerRegistration.h"
 #include "SWServerWorker.h"
 #include "ServiceWorkerContextData.h"
@@ -57,6 +58,7 @@ SWServer::~SWServer()
 {
     RELEASE_ASSERT(m_connections.isEmpty());
     RELEASE_ASSERT(m_registrations.isEmpty());
+    RELEASE_ASSERT(m_jobQueues.isEmpty());
 
     ASSERT(m_taskQueue.isEmpty());
     ASSERT(m_taskReplyQueue.isEmpty());
@@ -68,6 +70,25 @@ SWServer::~SWServer()
     ASSERT(!m_taskThread);
 }
 
+SWServerRegistration* SWServer::getRegistration(const ServiceWorkerRegistrationKey& registrationKey)
+{
+    ASSERT(!isMainThread());
+    return m_registrations.get(registrationKey);
+}
+
+void SWServer::addRegistration(std::unique_ptr<SWServerRegistration>&& registration)
+{
+    ASSERT(!isMainThread());
+    auto key = registration->key();
+    m_registrations.add(key, WTFMove(registration));
+}
+
+void SWServer::removeRegistration(const ServiceWorkerRegistrationKey& registrationKey)
+{
+    ASSERT(!isMainThread());
+    m_registrations.remove(registrationKey);
+}
+
 void SWServer::Connection::scheduleJobInServer(const ServiceWorkerJobData& jobData)
 {
     LOG(ServiceWorker, "Scheduling ServiceWorker job %" PRIu64 "-%" PRIu64 " in server", jobData.connectionIdentifier(), jobData.identifier());
@@ -86,9 +107,9 @@ void SWServer::Connection::scriptContextFailedToStart(const ServiceWorkerRegistr
     m_server.scriptContextFailedToStart(*this, registrationKey, workerID, message);
 }
 
-void SWServer::Connection::scriptContextStarted(const ServiceWorkerRegistrationKey& registrationKey, uint64_t identifier, const String& workerID)
+void SWServer::Connection::scriptContextStarted(const ServiceWorkerRegistrationKey& registrationKey, uint64_t serviceWorkerIdentifier, const String& workerID)
 {
-    m_server.scriptContextStarted(*this, registrationKey, identifier, workerID);
+    m_server.scriptContextStarted(*this, registrationKey, serviceWorkerIdentifier, workerID);
 }
 
 SWServer::SWServer()
@@ -102,9 +123,9 @@ void SWServer::scheduleJob(const ServiceWorkerJobData& jobData)
 {
     ASSERT(m_connections.contains(jobData.connectionIdentifier()));
 
-    auto result = m_registrations.add(jobData.registrationKey(), nullptr);
+    auto result = m_jobQueues.add(jobData.registrationKey(), nullptr);
     if (result.isNewEntry)
-        result.iterator->value = std::make_unique<SWServerRegistration>(*this, jobData.registrationKey());
+        result.iterator->value = std::make_unique<SWServerJobQueue>(*this, jobData.registrationKey());
 
     ASSERT(result.iterator->value);
 
@@ -156,27 +177,27 @@ void SWServer::scriptFetchFinished(Connection& connection, const ServiceWorkerFe
 
     ASSERT(m_connections.contains(result.connectionIdentifier));
 
-    auto registration = m_registrations.get(result.registrationKey);
-    if (!registration)
+    auto jobQueue = m_jobQueues.get(result.registrationKey);
+    if (!jobQueue)
         return;
 
-    registration->scriptFetchFinished(connection, result);
+    jobQueue->scriptFetchFinished(connection, result);
 }
 
 void SWServer::scriptContextFailedToStart(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey, const String& workerID, const String& message)
 {
     ASSERT(m_connections.contains(connection.identifier()));
     
-    if (auto* registration = m_registrations.get(registrationKey))
-        registration->scriptContextFailedToStart(connection, workerID, message);
+    if (auto* jobQueue = m_jobQueues.get(registrationKey))
+        jobQueue->scriptContextFailedToStart(connection, workerID, message);
 }
 
-void SWServer::scriptContextStarted(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey, uint64_t identifier, const String& workerID)
+void SWServer::scriptContextStarted(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey, uint64_t serviceWorkerIdentifier, const String& workerID)
 {
     ASSERT(m_connections.contains(connection.identifier()));
 
-    if (auto* registration = m_registrations.get(registrationKey))
-        registration->scriptContextStarted(connection, identifier, workerID);
+    if (auto* jobQueue = m_jobQueues.get(registrationKey))
+        jobQueue->scriptContextStarted(connection, serviceWorkerIdentifier, workerID);
 }
 
 Ref<SWServerWorker> SWServer::updateWorker(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey, const URL& url, const String& script, WorkerType type)
index 1d68597..3bd57d4 100644 (file)
@@ -40,6 +40,7 @@
 
 namespace WebCore {
 
+class SWServerJobQueue;
 class SWServerRegistration;
 class SWServerWorker;
 struct ExceptionData;
@@ -55,7 +56,7 @@ public:
         WEBCORE_EXPORT virtual ~Connection();
 
         WEBCORE_EXPORT void scriptContextFailedToStart(const ServiceWorkerRegistrationKey&, const String& workerID, const String& message);
-        WEBCORE_EXPORT void scriptContextStarted(const ServiceWorkerRegistrationKey&, uint64_t identifier, const String& workerID);
+        WEBCORE_EXPORT void scriptContextStarted(const ServiceWorkerRegistrationKey&, uint64_t serviceWorkerIdentifier, const String& workerID);
 
     protected:
         WEBCORE_EXPORT Connection(SWServer&, uint64_t identifier);
@@ -80,6 +81,10 @@ public:
     WEBCORE_EXPORT SWServer();
     WEBCORE_EXPORT ~SWServer();
 
+    SWServerRegistration* getRegistration(const ServiceWorkerRegistrationKey&);
+    void addRegistration(std::unique_ptr<SWServerRegistration>&&);
+    void removeRegistration(const ServiceWorkerRegistrationKey&);
+
     void scheduleJob(const ServiceWorkerJobData&);
     void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
     void resolveRegistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&);
@@ -100,10 +105,11 @@ private:
 
     void scriptFetchFinished(Connection&, const ServiceWorkerFetchResult&);
     void scriptContextFailedToStart(Connection&, const ServiceWorkerRegistrationKey&, const String& workerID, const String& message);
-    void scriptContextStarted(Connection&, const ServiceWorkerRegistrationKey&, uint64_t identifier, const String& workerID);
+    void scriptContextStarted(Connection&, const ServiceWorkerRegistrationKey&, uint64_t serviceWorkerIdentifier, const String& workerID);
 
     HashMap<uint64_t, Connection*> m_connections;
     HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations;
+    HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerJobQueue>> m_jobQueues;
 
     HashMap<String, Ref<SWServerWorker>> m_workersByID;
 
diff --git a/Source/WebCore/workers/service/server/SWServerJobQueue.cpp b/Source/WebCore/workers/service/server/SWServerJobQueue.cpp
new file mode 100644 (file)
index 0000000..f20345f
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SWServerJobQueue.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "ExceptionData.h"
+#include "SWServer.h"
+#include "SWServerWorker.h"
+#include "SecurityOrigin.h"
+#include "ServiceWorkerFetchResult.h"
+#include "ServiceWorkerRegistrationData.h"
+#include "ServiceWorkerUpdateViaCache.h"
+#include "WorkerType.h"
+
+namespace WebCore {
+
+SWServerJobQueue::SWServerJobQueue(SWServer& server, const ServiceWorkerRegistrationKey& key)
+    : m_jobTimer(*this, &SWServerJobQueue::startNextJob)
+    , m_server(server)
+    , m_registrationKey(key)
+{
+}
+
+SWServerJobQueue::~SWServerJobQueue()
+{
+    ASSERT(m_jobQueue.isEmpty());
+}
+
+void SWServerJobQueue::enqueueJob(const ServiceWorkerJobData& jobData)
+{
+    // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.
+    // If it is, stack it along with that job.
+
+    m_jobQueue.append(jobData);
+
+    if (m_currentJob)
+        return;
+
+    if (!m_jobTimer.isActive())
+        m_jobTimer.startOneShot(0_s);
+}
+
+void SWServerJobQueue::scriptFetchFinished(SWServer::Connection& connection, const ServiceWorkerFetchResult& result)
+{
+    ASSERT(isMainThread());
+    ASSERT(m_currentJob && m_currentJob->identifier() == result.jobIdentifier);
+
+    if (!result.scriptError.isNull()) {
+        rejectCurrentJob(ExceptionData { UnknownError, makeString("Script URL ", m_currentJob->scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription()) });
+
+        // If newestWorker is null, invoke Clear Registration algorithm passing this registration as its argument.
+        // FIXME: We don't have "clear registration" yet.
+
+        return;
+    }
+
+    // FIXME: If the script data matches byte-for-byte with the existing newestWorker,
+    // then resolve and finish the job without doing anything further.
+
+    // FIXME: Support the proper worker type (classic vs module)
+    m_server.updateWorker(connection, m_registrationKey, m_currentJob->scriptURL, result.script, WorkerType::Classic);
+}
+
+void SWServerJobQueue::scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message)
+{
+    ASSERT(isMainThread());
+    // FIXME: Install has failed. Run the install failed substeps
+    // Run the Update Worker State algorithm passing registration’s installing worker and redundant as the arguments.
+    // Run the Update Registration State algorithm passing registration, "installing" and null as the arguments.
+    // If newestWorker is null, invoke Clear Registration algorithm passing registration as its argument.
+
+    UNUSED_PARAM(workerID);
+    UNUSED_PARAM(message);
+}
+
+void SWServerJobQueue::scriptContextStarted(SWServer::Connection&, uint64_t serviceWorkerIdentifier, const String& workerID)
+{
+    ASSERT(isMainThread());
+    UNUSED_PARAM(workerID);
+
+    m_server.postTask(createCrossThreadTask(*this, &SWServerJobQueue::resolveCurrentRegistrationJobOnMainThead, serviceWorkerIdentifier));
+}
+
+void SWServerJobQueue::startNextJob()
+{
+    ASSERT(isMainThread());
+    ASSERT(!m_currentJob);
+    ASSERT(!m_jobQueue.isEmpty());
+
+    m_currentJob = std::make_unique<ServiceWorkerJobData>(m_jobQueue.takeFirst().isolatedCopy());
+
+    switch (m_currentJob->type) {
+    case ServiceWorkerJobType::Register:
+        m_server.postTask(createCrossThreadTask(*this, &SWServerJobQueue::runRegisterJob, *m_currentJob));
+        return;
+    case ServiceWorkerJobType::Unregister:
+        m_server.postTask(createCrossThreadTask(*this, &SWServerJobQueue::runUnregisterJob, *m_currentJob));
+        return;
+    }
+
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+void SWServerJobQueue::runRegisterJob(const ServiceWorkerJobData& job)
+{
+    ASSERT(!isMainThread());
+    ASSERT(job.type == ServiceWorkerJobType::Register);
+
+    if (!shouldTreatAsPotentiallyTrustworthy(job.scriptURL))
+        return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Script URL is not potentially trustworthy") });
+
+    // If the origin of job’s script url is not job’s referrer's origin, then:
+    if (!protocolHostAndPortAreEqual(job.scriptURL, job.clientCreationURL))
+        return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Script origin does not match the registering client's origin") });
+
+    // If the origin of job’s scope url is not job’s referrer's origin, then:
+    if (!protocolHostAndPortAreEqual(job.scopeURL, job.clientCreationURL))
+        return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Scope origin does not match the registering client's origin") });
+
+    // If registration is not null (in our parlance "empty"), then:
+    if (auto* registration = m_server.getRegistration(m_registrationKey)) {
+        registration->setIsUninstalling(false);
+        auto* newestWorker = registration->getNewestWorker();
+        if (newestWorker && equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()) && job.registrationOptions.updateViaCache == registration->updateViaCache()) {
+            resolveWithRegistrationOnMainThread(*registration);
+            return;
+        }
+    } else {
+        auto newRegistration = std::make_unique<SWServerRegistration>(m_registrationKey, job.registrationOptions.updateViaCache, job.scopeURL, job.scriptURL);
+        m_server.addRegistration(WTFMove(newRegistration));
+    }
+
+    runUpdateJob(job);
+}
+
+void SWServerJobQueue::runUnregisterJob(const ServiceWorkerJobData& job)
+{
+    ASSERT(!isMainThread());
+
+    // If the origin of job’s scope url is not job's client's origin, then:
+    if (!protocolHostAndPortAreEqual(job.scopeURL, job.clientCreationURL))
+        return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Origin of scope URL does not match the client's origin") });
+
+    // Let registration be the result of running "Get Registration" algorithm passing job’s scope url as the argument.
+    auto* registration = m_server.getRegistration(m_registrationKey);
+
+    // If registration is null, then:
+    if (!registration || registration->isUninstalling()) {
+        // Invoke Resolve Job Promise with job and false.
+        resolveWithUnregistrationResultOnMainThread(false);
+        return;
+    }
+
+    // Set registration’s uninstalling flag.
+    registration->setIsUninstalling(true);
+
+    // Invoke Resolve Job Promise with job and true.
+    resolveWithUnregistrationResultOnMainThread(true);
+
+    // FIXME: Invoke Try Clear Registration with registration.
+}
+
+void SWServerJobQueue::runUpdateJob(const ServiceWorkerJobData& job)
+{
+    auto* registration = m_server.getRegistration(m_registrationKey);
+
+    // If registration is null (in our parlance "empty") or registration’s uninstalling flag is set, then:
+    if (!registration)
+        return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a null/nonexistent service worker registration") });
+    if (registration->isUninstalling())
+        return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker registration that is uninstalling") });
+
+    // If job’s job type is update, and newestWorker’s script url does not equal job’s script url with the exclude fragments flag set, then:
+    auto* newestWorker = registration->getNewestWorker();
+    if (newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))
+        return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker with a requested script URL whose newest worker has a different script URL") });
+
+    startScriptFetchFromMainThread();
+}
+
+void SWServerJobQueue::rejectWithExceptionOnMainThread(const ExceptionData& exception)
+{
+    ASSERT(!isMainThread());
+    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerJobQueue::rejectCurrentJob, exception));
+}
+
+void SWServerJobQueue::resolveWithRegistrationOnMainThread(SWServerRegistration& registration)
+{
+    ASSERT(!isMainThread());
+    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerJobQueue::resolveCurrentRegistrationJob, registration.data()));
+}
+
+void SWServerJobQueue::resolveCurrentRegistrationJobOnMainThead(uint64_t serviceWorkerIdentifier)
+{
+    ASSERT(!isMainThread());
+    auto* registration = m_server.getRegistration(m_registrationKey);
+    ASSERT(registration);
+    registration->setActiveServiceWorkerIdentifier(serviceWorkerIdentifier);
+    resolveWithRegistrationOnMainThread(*registration);
+}
+
+void SWServerJobQueue::resolveWithUnregistrationResultOnMainThread(bool unregistrationResult)
+{
+    ASSERT(!isMainThread());
+    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerJobQueue::resolveCurrentUnregistrationJob, unregistrationResult));
+}
+
+void SWServerJobQueue::startScriptFetchFromMainThread()
+{
+    ASSERT(!isMainThread());
+    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerJobQueue::startScriptFetchForCurrentJob));
+}
+
+void SWServerJobQueue::rejectCurrentJob(const ExceptionData& exceptionData)
+{
+    ASSERT(isMainThread());
+    ASSERT(m_currentJob);
+
+    m_server.rejectJob(*m_currentJob, exceptionData);
+
+    finishCurrentJob();
+}
+
+void SWServerJobQueue::resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData& data)
+{
+    ASSERT(isMainThread());
+    ASSERT(m_currentJob);
+    ASSERT(m_currentJob->type == ServiceWorkerJobType::Register);
+
+    m_server.resolveRegistrationJob(*m_currentJob, data);
+
+    finishCurrentJob();
+}
+
+void SWServerJobQueue::resolveCurrentUnregistrationJob(bool unregistrationResult)
+{
+    ASSERT(isMainThread());
+    ASSERT(m_currentJob);
+    ASSERT(m_currentJob->type == ServiceWorkerJobType::Unregister);
+
+    m_server.resolveUnregistrationJob(*m_currentJob, m_registrationKey, unregistrationResult);
+
+    finishCurrentJob();
+}
+
+void SWServerJobQueue::startScriptFetchForCurrentJob()
+{
+    ASSERT(isMainThread());
+    ASSERT(m_currentJob);
+
+    m_server.startScriptFetch(*m_currentJob);
+}
+
+void SWServerJobQueue::finishCurrentJob()
+{
+    ASSERT(isMainThread());
+    ASSERT(m_currentJob);
+    ASSERT(!m_jobTimer.isActive());
+
+    m_currentJob = nullptr;
+    if (m_jobQueue.isEmpty())
+        return;
+
+    startNextJob();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
diff --git a/Source/WebCore/workers/service/server/SWServerJobQueue.h b/Source/WebCore/workers/service/server/SWServerJobQueue.h
new file mode 100644 (file)
index 0000000..4095b3b
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "SWServer.h"
+#include "ServiceWorkerJobData.h"
+#include "Timer.h"
+#include <wtf/Deque.h>
+
+namespace WebCore {
+
+class SWServerJobQueue {
+public:
+    explicit SWServerJobQueue(SWServer&, const ServiceWorkerRegistrationKey&);
+    SWServerJobQueue(const SWServerRegistration&) = delete;
+    ~SWServerJobQueue();
+
+    void enqueueJob(const ServiceWorkerJobData&);
+    void scriptFetchFinished(SWServer::Connection&, const ServiceWorkerFetchResult&);
+    void scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message);
+    void scriptContextStarted(SWServer::Connection&, uint64_t serviceWorkerIdentifier, const String& workerID);
+
+private:
+    void jobTimerFired();
+    void startNextJob();
+    void rejectCurrentJob(const ExceptionData&);
+    void resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData&);
+    void resolveCurrentUnregistrationJob(bool unregistrationResult);
+    void startScriptFetchForCurrentJob();
+    void finishCurrentJob();
+
+    void runRegisterJob(const ServiceWorkerJobData&);
+    void runUnregisterJob(const ServiceWorkerJobData&);
+    void runUpdateJob(const ServiceWorkerJobData&);
+
+    void rejectWithExceptionOnMainThread(const ExceptionData&);
+    void resolveWithRegistrationOnMainThread(SWServerRegistration&);
+    void resolveCurrentRegistrationJobOnMainThead(uint64_t serviceWorkerIdentifier);
+    void resolveWithUnregistrationResultOnMainThread(bool);
+    void startScriptFetchFromMainThread();
+    bool isEmpty();
+
+    Deque<ServiceWorkerJobData> m_jobQueue;
+    std::unique_ptr<ServiceWorkerJobData> m_currentJob;
+
+    Timer m_jobTimer;
+    SWServer& m_server;
+    ServiceWorkerRegistrationKey m_registrationKey;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
index aacad4d..cc27c86 100644 (file)
 
 namespace WebCore {
 
-SWServerRegistration::SWServerRegistration(SWServer& server, const ServiceWorkerRegistrationKey& key)
-    : m_jobTimer(*this, &SWServerRegistration::startNextJob)
-    , m_server(server)
-    , m_registrationKey(key)
+SWServerRegistration::SWServerRegistration(const ServiceWorkerRegistrationKey& key, ServiceWorkerUpdateViaCache updateViaCache, const URL& scopeURL, const URL& scriptURL)
+    : m_registrationKey(key)
+    , m_updateViaCache(updateViaCache)
+    , m_scopeURL(scopeURL.isolatedCopy())
+    , m_scriptURL(scriptURL.isolatedCopy())
 {
+    m_scopeURL.removeFragmentIdentifier();
 }
 
 SWServerRegistration::~SWServerRegistration()
 {
-    ASSERT(m_jobQueue.isEmpty());
-}
-
-void SWServerRegistration::enqueueJob(const ServiceWorkerJobData& jobData)
-{
-    // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.
-    // If it is, stack it along with that job.
-
-    m_jobQueue.append(jobData);
-
-    if (m_currentJob)
-        return;
-
-    if (!m_jobTimer.isActive())
-        m_jobTimer.startOneShot(0_s);
-}
-
-void SWServerRegistration::scriptFetchFinished(SWServer::Connection& connection, const ServiceWorkerFetchResult& result)
-{
-    ASSERT(m_currentJob && m_currentJob->identifier() == result.jobIdentifier);
-
-    if (!result.scriptError.isNull()) {
-        rejectCurrentJob(ExceptionData { UnknownError, makeString("Script URL ", m_currentJob->scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription()) });
-        
-        // If newestWorker is null, invoke Clear Registration algorithm passing this registration as its argument.
-        // FIXME: We don't have "clear registration" yet.
-
-        return;
-    }
-
-    m_lastUpdateTime = currentTime();
-    
-    // FIXME: If the script data matches byte-for-byte with the existing newestWorker,
-    // then resolve and finish the job without doing anything further.
-
-    // FIXME: Support the proper worker type (classic vs module)
-    m_server.updateWorker(connection, m_registrationKey, m_currentJob->scriptURL, result.script, WorkerType::Classic);
-}
-
-void SWServerRegistration::scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message)
-{
-    // FIXME: Install has failed. Run the install failed substeps
-    // Run the Update Worker State algorithm passing registration’s installing worker and redundant as the arguments.
-    // Run the Update Registration State algorithm passing registration, "installing" and null as the arguments.
-    // If newestWorker is null, invoke Clear Registration algorithm passing registration as its argument.
-
-    UNUSED_PARAM(workerID);
-    UNUSED_PARAM(message);
-}
-
-void SWServerRegistration::scriptContextStarted(SWServer::Connection&, uint64_t identifier, const String& workerID)
-{
-    UNUSED_PARAM(workerID);
-    resolveCurrentRegistrationJob(ServiceWorkerRegistrationData { m_registrationKey, identifier, m_scopeURL, m_scriptURL, m_updateViaCache.value_or(ServiceWorkerUpdateViaCache::Imports) });
-}
-
-void SWServerRegistration::startNextJob()
-{
-    ASSERT(isMainThread());
-    ASSERT(!m_currentJob);
-    ASSERT(!m_jobQueue.isEmpty());
-
-    m_currentJob = std::make_unique<ServiceWorkerJobData>(m_jobQueue.takeFirst().isolatedCopy());
-
-    switch (m_currentJob->type) {
-    case ServiceWorkerJobType::Register:
-        m_server.postTask(createCrossThreadTask(*this, &SWServerRegistration::runRegisterJob, *m_currentJob));
-        return;
-    case ServiceWorkerJobType::Unregister:
-        m_server.postTask(createCrossThreadTask(*this, &SWServerRegistration::runUnregisterJob, *m_currentJob));
-        return;
-    }
-
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-bool SWServerRegistration::isEmpty()
-{
-    ASSERT(!isMainThread());
-
-    // Having or not-having an m_updateViaCache flag is currently
-    // the signal as to whether or not this is an empty (i.e. "new") registration.
-    // There will be a more explicit signal in the near future.
-    return !m_updateViaCache;
 }
 
 SWServerWorker* SWServerRegistration::getNewestWorker()
@@ -145,163 +63,11 @@ SWServerWorker* SWServerRegistration::getNewestWorker()
     return m_activeWorker.get();
 }
 
-void SWServerRegistration::runRegisterJob(const ServiceWorkerJobData& job)
-{
-    ASSERT(!isMainThread());
-    ASSERT(job.type == ServiceWorkerJobType::Register);
-
-    if (!shouldTreatAsPotentiallyTrustworthy(job.scriptURL))
-        return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Script URL is not potentially trustworthy") });
-
-    // If the origin of job’s script url is not job’s referrer's origin, then:
-    if (!protocolHostAndPortAreEqual(job.scriptURL, job.clientCreationURL))
-        return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Script origin does not match the registering client's origin") });
-
-    // If the origin of job’s scope url is not job’s referrer's origin, then:
-    if (!protocolHostAndPortAreEqual(job.scopeURL, job.clientCreationURL))
-        return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Scope origin does not match the registering client's origin") });
-
-    // If registration is not null (in our parlance "empty"), then:
-    if (!isEmpty()) {
-        ASSERT(m_updateViaCache);
-
-        m_uninstalling = false;
-        auto* newestWorker = getNewestWorker();
-        if (newestWorker && equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()) && job.registrationOptions.updateViaCache == *m_updateViaCache) {
-            resolveWithRegistrationOnMainThread();
-            return;
-        }
-    } else {
-        m_scopeURL = job.scopeURL.isolatedCopy();
-        m_scopeURL.removeFragmentIdentifier();
-        m_scriptURL = job.scriptURL.isolatedCopy();
-        m_updateViaCache = job.registrationOptions.updateViaCache;
-    }
-
-    runUpdateJob(job);
-}
-
-void SWServerRegistration::runUnregisterJob(const ServiceWorkerJobData& job)
-{
-    // If the origin of job’s scope url is not job's client's origin, then:
-    if (!protocolHostAndPortAreEqual(job.scopeURL, job.clientCreationURL))
-        return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Origin of scope URL does not match the client's origin") });
-
-    // Let registration be the result of running "Get Registration" algorithm passing job’s scope url as the argument.
-    // If registration is null, then:
-    if (isEmpty() || m_uninstalling) {
-        // Invoke Resolve Job Promise with job and false.
-        resolveWithUnregistrationResultOnMainThread(false);
-        return;
-    }
-
-    // Set registration’s uninstalling flag.
-    m_uninstalling = true;
-
-    // Invoke Resolve Job Promise with job and true.
-    resolveWithUnregistrationResultOnMainThread(true);
-
-    // FIXME: Invoke Try Clear Registration with registration.
-}
-
-void SWServerRegistration::runUpdateJob(const ServiceWorkerJobData& job)
-{
-    // If registration is null (in our parlance "empty") or registration’s uninstalling flag is set, then:
-    if (isEmpty())
-        return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a null/nonexistent service worker registration") });
-    if (m_uninstalling)
-        return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker registration that is uninstalling") });
-
-    // If job’s job type is update, and newestWorker’s script url does not equal job’s script url with the exclude fragments flag set, then:
-    auto* newestWorker = getNewestWorker();
-    if (newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))
-        return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker with a requested script URL whose newest worker has a different script URL") });
-
-    startScriptFetchFromMainThread();
-}
-
-void SWServerRegistration::rejectWithExceptionOnMainThread(const ExceptionData& exception)
-{
-    ASSERT(!isMainThread());
-    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::rejectCurrentJob, exception));
-}
-
-void SWServerRegistration::resolveWithRegistrationOnMainThread()
-{
-    ASSERT(!isMainThread());
-    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::resolveCurrentRegistrationJob, data()));
-}
-
-void SWServerRegistration::resolveWithUnregistrationResultOnMainThread(bool unregistrationResult)
-{
-    ASSERT(!isMainThread());
-    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::resolveCurrentUnregistrationJob, unregistrationResult));
-}
-
-void SWServerRegistration::startScriptFetchFromMainThread()
-{
-    ASSERT(!isMainThread());
-    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::startScriptFetchForCurrentJob));
-}
-
-void SWServerRegistration::rejectCurrentJob(const ExceptionData& exceptionData)
-{
-    ASSERT(isMainThread());
-    ASSERT(m_currentJob);
-
-    m_server.rejectJob(*m_currentJob, exceptionData);
-
-    finishCurrentJob();
-}
-
-void SWServerRegistration::resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData& data)
-{
-    ASSERT(isMainThread());
-    ASSERT(m_currentJob);
-    ASSERT(m_currentJob->type == ServiceWorkerJobType::Register);
-
-    m_server.resolveRegistrationJob(*m_currentJob, data);
-
-    finishCurrentJob();
-}
-
-void SWServerRegistration::resolveCurrentUnregistrationJob(bool unregistrationResult)
-{
-    ASSERT(isMainThread());
-    ASSERT(m_currentJob);
-    ASSERT(m_currentJob->type == ServiceWorkerJobType::Unregister);
-
-    m_server.resolveUnregistrationJob(*m_currentJob, m_registrationKey, unregistrationResult);
-
-    finishCurrentJob();
-}
-
-void SWServerRegistration::startScriptFetchForCurrentJob()
-{
-    ASSERT(isMainThread());
-    ASSERT(m_currentJob);
-
-    m_server.startScriptFetch(*m_currentJob);
-}
-
-void SWServerRegistration::finishCurrentJob()
-{
-    ASSERT(m_currentJob);
-    ASSERT(!m_jobTimer.isActive());
-
-    m_currentJob = nullptr;
-    if (m_jobQueue.isEmpty())
-        return;
-
-    startNextJob();
-}
-
 ServiceWorkerRegistrationData SWServerRegistration::data() const
 {
-    return { m_registrationKey, identifier(), m_scopeURL, m_scriptURL, m_updateViaCache.value_or(ServiceWorkerUpdateViaCache::Imports) };
+    return { m_registrationKey, identifier(), m_activeServiceWorkerIdentifier, m_scopeURL, m_scriptURL, m_updateViaCache };
 }
 
-
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 35d7f5f..8e070b5 100644 (file)
 #if ENABLE(SERVICE_WORKER)
 
 #include "SWServer.h"
-#include "ServiceWorkerJobData.h"
 #include "ServiceWorkerRegistrationData.h"
-#include "Timer.h"
-#include <wtf/Deque.h>
 #include <wtf/Identified.h>
 
 namespace WebCore {
 
-class SWServer;
 class SWServerWorker;
 struct ExceptionData;
 struct ServiceWorkerFetchResult;
 
 class SWServerRegistration : public ThreadSafeIdentified<SWServerRegistration> {
 public:
-    explicit SWServerRegistration(SWServer&, const ServiceWorkerRegistrationKey&);
-    SWServerRegistration(const SWServerRegistration&) = delete;
+    SWServerRegistration(const ServiceWorkerRegistrationKey&, ServiceWorkerUpdateViaCache, const URL& scopeURL, const URL& scriptURL);
     ~SWServerRegistration();
 
-    void enqueueJob(const ServiceWorkerJobData&);
-    void scriptFetchFinished(SWServer::Connection&, const ServiceWorkerFetchResult&);
-    void scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message);
-    void scriptContextStarted(SWServer::Connection&, uint64_t identifier, const String& workerID);
-    
-    ServiceWorkerRegistrationData data() const;
+    const ServiceWorkerRegistrationKey& key() const { return m_registrationKey; }
 
-private:
-    void jobTimerFired();
-    void startNextJob();
-    void rejectCurrentJob(const ExceptionData&);
-    void resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData&);
-    void resolveCurrentUnregistrationJob(bool unregistrationResult);
-    void startScriptFetchForCurrentJob();
-    void finishCurrentJob();
-
-    void runRegisterJob(const ServiceWorkerJobData&);
-    void runUnregisterJob(const ServiceWorkerJobData&);
-    void runUpdateJob(const ServiceWorkerJobData&);
-
-    void rejectWithExceptionOnMainThread(const ExceptionData&);
-    void resolveWithRegistrationOnMainThread();
-    void resolveWithUnregistrationResultOnMainThread(bool);
-    void startScriptFetchFromMainThread();
-    bool isEmpty();
     SWServerWorker* getNewestWorker();
+    ServiceWorkerRegistrationData data() const;
+
+    bool isUninstalling() const { return m_uninstalling; }
+    void setIsUninstalling(bool value) { m_uninstalling = value; }
 
-    Deque<ServiceWorkerJobData> m_jobQueue;
-    std::unique_ptr<ServiceWorkerJobData> m_currentJob;
+    void setLastUpdateTime(double time) { m_lastUpdateTime = time; }
+    ServiceWorkerUpdateViaCache updateViaCache() const { return m_updateViaCache; }
+
+    void setActiveServiceWorkerIdentifier(uint64_t identifier) { m_activeServiceWorkerIdentifier = identifier; }
+
+private:
+    ServiceWorkerRegistrationKey m_registrationKey;
+    ServiceWorkerUpdateViaCache m_updateViaCache;
+    URL m_scopeURL;
+    URL m_scriptURL;
 
     bool m_uninstalling { false };
     std::unique_ptr<SWServerWorker> m_installingWorker;
     std::unique_ptr<SWServerWorker> m_waitingWorker;
     std::unique_ptr<SWServerWorker> m_activeWorker;
-    URL m_scopeURL;
-    URL m_scriptURL;
-    std::optional<ServiceWorkerUpdateViaCache> m_updateViaCache;
-    
-    double m_lastUpdateTime { 0 };
 
-    Timer m_jobTimer;
-    SWServer& m_server;
-    ServiceWorkerRegistrationKey m_registrationKey;
+    uint64_t m_activeServiceWorkerIdentifier { 0 };
+
+    double m_lastUpdateTime { 0 };
 };
 
 } // namespace WebCore