Introduce ServerWorkerRegistration task queues.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Aug 2017 18:57:44 +0000 (18:57 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Aug 2017 18:57:44 +0000 (18:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175851

Reviewed by Andy Estes.

Source/WebCore:

Test: http/tests/workers/service/registration-task-queue-scheduling-1.html

This change introduces:
- A task thread/queue owned by each SWServer object.
- The SWServerRegistration object, which is the in-server representation of a
  service worker registration scope.
- A registration job queue per SWServerRegistration object which actually runs the
  jobs as tasks on the owning SWServer's thread.

With that infrastructure in place, it moves the "register" job to something that is
scheduled and rejected asynchronously, as opposed to synchronously rejected.

The test verifies that two different registration scopes (localhost and 127.0.0.1)
can both spam the SWServer with registration requests, but neither of their queues
starve the other.

The rest of this change is a lot of support and plumbing for making the above happen.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* dom/ExceptionData.cpp:
(WebCore::ExceptionData::isolatedCopy const):
* dom/ExceptionData.h:

* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::addRegistration):
(WebCore::ServiceWorkerContainer::connectionIdentifier):
* workers/service/ServiceWorkerContainer.h:

* workers/service/ServiceWorkerJob.cpp:
(WebCore::ServiceWorkerJob::ServiceWorkerJob):
(WebCore::ServiceWorkerJob::data const): Deleted.
* workers/service/ServiceWorkerJob.h:
(WebCore::ServiceWorkerJob::create):
(WebCore::ServiceWorkerJob::data const):
(WebCore::ServiceWorkerJob::createRegisterJob): Deleted.

* workers/service/ServiceWorkerJobClient.h:

* workers/service/ServiceWorkerJobData.cpp:
(WebCore::ServiceWorkerJobData::ServiceWorkerJobData):
(WebCore::ServiceWorkerJobData::registrationKey const):
(WebCore::ServiceWorkerJobData::isolatedCopy const):
* workers/service/ServiceWorkerJobData.h:
(WebCore::ServiceWorkerJobData::jobIdentifier const):
(WebCore::ServiceWorkerJobData::connectionIdentifier const):
(WebCore::ServiceWorkerJobData::encode const):
(WebCore::ServiceWorkerJobData::decode):

* workers/service/ServiceWorkerRegistrationKey.cpp:
(WebCore::ServiceWorkerRegistrationKey::emptyKey):
(WebCore::ServiceWorkerRegistrationKey::hash const):
(WebCore::ServiceWorkerRegistrationKey::operator== const):
* workers/service/ServiceWorkerRegistrationKey.h:
(WTF::ServiceWorkerRegistrationKeyHash::hash):
(WTF::ServiceWorkerRegistrationKeyHash::equal):
(WTF::HashTraits<WebCore::ServiceWorkerRegistrationKey>::emptyValue):
(WTF::HashTraits<WebCore::ServiceWorkerRegistrationKey>::constructDeletedValue):
(WTF::HashTraits<WebCore::ServiceWorkerRegistrationKey>::isDeletedValue):

* workers/service/ServiceWorkerRegistrationOptions.cpp:
(WebCore::RegistrationOptions::isolatedCopy const):
* workers/service/ServiceWorkerRegistrationOptions.h:
(WebCore::RegistrationOptions::encode const):
(WebCore::RegistrationOptions::decode):

* workers/service/server/SWClientConnection.h:

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::Connection):
(WebCore::SWServer::~SWServer):
(WebCore::SWServer::Connection::scheduleJobInServer):
(WebCore::SWServer::SWServer):
(WebCore::SWServer::scheduleJob):
(WebCore::SWServer::rejectJob):
(WebCore::SWServer::taskThreadEntryPoint):
(WebCore::SWServer::postTask):
(WebCore::SWServer::postTaskReply):
(WebCore::SWServer::handleTaskRepliesOnMainThread):
(WebCore::SWServer::registerConnection):
(WebCore::SWServer::unregisterConnection):
* workers/service/server/SWServer.h:
(WebCore::SWServer::Connection::identifier const):

* workers/service/server/SWServerRegistration.cpp: Added.
(WebCore::SWServerRegistration::SWServerRegistration):
(WebCore::SWServerRegistration::~SWServerRegistration):
(WebCore::SWServerRegistration::enqueueJob):
(WebCore::SWServerRegistration::startNextJob):
(WebCore::SWServerRegistration::performCurrentJob):
(WebCore::SWServerRegistration::rejectCurrentJob):
(WebCore::SWServerRegistration::finishCurrentJob):
* workers/service/server/SWServerRegistration.h:

Source/WebKit:

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::WebSWServerConnection):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
(WebKit::WebSWServerConnection::identifier const): Deleted.

* WebProcess/Storage/WebSWClientConnection.h:
(WebKit::WebSWClientConnection::identifier const): Deleted.

LayoutTests:

* http/tests/workers/service/registration-task-queue-scheduling-1-expected.txt: Added.
* http/tests/workers/service/registration-task-queue-scheduling-1.html: Added.
* http/tests/workers/service/resources/registration-task-queue-scheduling-1-second-window.html: Added.
* http/tests/workers/service/resources/registration-task-queue-scheduling-1.js: Added.

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

30 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/registration-task-queue-scheduling-1-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/registration-task-queue-scheduling-1.html [new file with mode: 0644]
LayoutTests/http/tests/workers/service/resources/registration-task-queue-scheduling-1-second-window.html [new file with mode: 0644]
LayoutTests/http/tests/workers/service/resources/registration-task-queue-scheduling-1.js [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/ExceptionData.cpp [moved from Source/WebCore/workers/service/ServiceWorkerRegistrationParameters.cpp with 87% similarity]
Source/WebCore/dom/ExceptionData.h
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerContainer.h
Source/WebCore/workers/service/ServiceWorkerJob.cpp
Source/WebCore/workers/service/ServiceWorkerJob.h
Source/WebCore/workers/service/ServiceWorkerJobClient.h
Source/WebCore/workers/service/ServiceWorkerJobData.cpp [new file with mode: 0644]
Source/WebCore/workers/service/ServiceWorkerJobData.h
Source/WebCore/workers/service/ServiceWorkerRegistrationKey.cpp [new file with mode: 0644]
Source/WebCore/workers/service/ServiceWorkerRegistrationKey.h [new file with mode: 0644]
Source/WebCore/workers/service/ServiceWorkerRegistrationOptions.cpp [moved from Source/WebCore/workers/service/ServiceWorkerRegistrationParameters.h with 84% similarity]
Source/WebCore/workers/service/ServiceWorkerRegistrationOptions.h
Source/WebCore/workers/service/server/SWClientConnection.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerRegistration.cpp [new file with mode: 0644]
Source/WebCore/workers/service/server/SWServerRegistration.h [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/WebProcess/Storage/WebSWClientConnection.h

index 6f4790d..17fd250 100644 (file)
@@ -1,3 +1,15 @@
+2017-08-25  Brady Eidson  <beidson@apple.com>
+
+        Introduce ServerWorkerRegistration task queues.
+        https://bugs.webkit.org/show_bug.cgi?id=175851
+
+        Reviewed by Andy Estes.
+
+        * http/tests/workers/service/registration-task-queue-scheduling-1-expected.txt: Added.
+        * http/tests/workers/service/registration-task-queue-scheduling-1.html: Added.
+        * http/tests/workers/service/resources/registration-task-queue-scheduling-1-second-window.html: Added.
+        * http/tests/workers/service/resources/registration-task-queue-scheduling-1.js: Added.
+
 2017-07-25  Frederic Wang  <fwang@igalia.com>
 
         Add flag allow-modals to iframe sandbox
diff --git a/LayoutTests/http/tests/workers/service/registration-task-queue-scheduling-1-expected.txt b/LayoutTests/http/tests/workers/service/registration-task-queue-scheduling-1-expected.txt
new file mode 100644 (file)
index 0000000..f914f50
--- /dev/null
@@ -0,0 +1,2 @@
+ALERT: Done
+
diff --git a/LayoutTests/http/tests/workers/service/registration-task-queue-scheduling-1.html b/LayoutTests/http/tests/workers/service/registration-task-queue-scheduling-1.html
new file mode 100644 (file)
index 0000000..913ea6a
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src="resources/sw-test-pre.js"></script>
+</head>
+<body>
+
+<script src="resources/registration-task-queue-scheduling-1.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/workers/service/resources/registration-task-queue-scheduling-1-second-window.html b/LayoutTests/http/tests/workers/service/resources/registration-task-queue-scheduling-1-second-window.html
new file mode 100644 (file)
index 0000000..206772f
--- /dev/null
@@ -0,0 +1,16 @@
+<script>
+
+if (!window.opener)
+       alert("This HTML file should not be opened directly")
+
+for (var i = 0; i < 1000; ++i) {
+       navigator.serviceWorker.register("empty-worker.js", { })
+       .then(function(r) {
+               alert("Popup window resolved successfully (unexpected)")
+               opener.postMessage("done", "*");
+       }, function(e) {
+               opener.postMessage("responded", "*");
+       })
+}
+
+</script>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/workers/service/resources/registration-task-queue-scheduling-1.js b/LayoutTests/http/tests/workers/service/resources/registration-task-queue-scheduling-1.js
new file mode 100644 (file)
index 0000000..127a3db
--- /dev/null
@@ -0,0 +1,60 @@
+// This test makes sure that two different windows from two different domains who spam SW registrations get responses intertwined with each other
+// as each registration should operate on its own task queue.
+
+if (location.hostname != "127.0.0.1")
+    alert("This test must be initiated from the hostname 127.0.0.1");
+
+window.onmessage = function(evt)
+{
+       if (evt.data == "done") {
+               alert("Error in popup window");
+               finishSWTest();
+       } else if (evt.data == "responded") {
+               if (!window.popupTimestamp)
+                       window.popupTimestamp = new Date();
+               
+               responded();
+       } else {
+               alert("Unexpected event from popup window");
+               finishSWTest();
+       }
+}
+
+function responded()
+{
+       if (!window.thisTimestamp) {
+               window.thisTimestamp = new Date();
+       
+               if (window.popupTimestamp)
+                       alert("Registrations in second window should not have responded before the first");
+       
+               return;
+       }
+       
+       if (!window.popupTimestamp) 
+               return;
+               
+       if (window.popupTimestamp < window.thisTimestamp)
+               alert("Popup should not have popped up before this main window");
+       else
+               alert("Done");
+       
+       finishSWTest();
+}
+
+for (var i = 0; i < 1000; ++i) {
+       navigator.serviceWorker.register("resources/empty-worker.js", { })
+       .then(function(r) {
+               console.log("Original window resolved successfully (unexpected)")
+               done();
+       }, function(e) {
+               if (e+"" != "UnknownError: serviceWorker job scheduling is not yet implemented") {
+                       alert("Unexpected error received from server");
+                       finishSWTest();
+               }
+               
+               responded();
+       })
+}
+
+otherWindow = window.open("http://localhost:8000/workers/service/resources/registration-task-queue-scheduling-1-second-window.html", "other");
index 7e34259..5966f85 100644 (file)
@@ -1545,6 +1545,7 @@ set(WebCore_SOURCES
     dom/EventNames.cpp
     dom/EventPath.cpp
     dom/EventTarget.cpp
+    dom/ExceptionData.cpp
     dom/ExtensionStyleSheets.cpp
     dom/FocusEvent.cpp
     dom/GenericEventQueue.cpp
@@ -2990,12 +2991,15 @@ set(WebCore_SOURCES
     workers/service/ServiceWorkerContainer.cpp
     workers/service/ServiceWorkerGlobalScope.cpp
     workers/service/ServiceWorkerJob.cpp
+    workers/service/ServiceWorkerJobData.cpp
     workers/service/ServiceWorkerProvider.cpp
     workers/service/ServiceWorkerRegistration.cpp
-    workers/service/ServiceWorkerRegistrationParameters.cpp
+    workers/service/ServiceWorkerRegistrationKey.cpp
+    workers/service/ServiceWorkerRegistrationOptions.cpp
 
     workers/service/server/SWClientConnection.cpp
     workers/service/server/SWServer.cpp
+    workers/service/server/SWServerRegistration.cpp
 
     xml/DOMParser.cpp
     xml/NativeXPathNSResolver.cpp
index 3e77f9a..9212c49 100644 (file)
@@ -1,3 +1,105 @@
+2017-08-25  Brady Eidson  <beidson@apple.com>
+
+        Introduce ServerWorkerRegistration task queues.
+        https://bugs.webkit.org/show_bug.cgi?id=175851
+
+        Reviewed by Andy Estes.
+
+        Test: http/tests/workers/service/registration-task-queue-scheduling-1.html
+
+        This change introduces:
+        - A task thread/queue owned by each SWServer object.
+        - The SWServerRegistration object, which is the in-server representation of a
+          service worker registration scope.
+        - A registration job queue per SWServerRegistration object which actually runs the
+          jobs as tasks on the owning SWServer's thread.
+
+        With that infrastructure in place, it moves the "register" job to something that is
+        scheduled and rejected asynchronously, as opposed to synchronously rejected.
+
+        The test verifies that two different registration scopes (localhost and 127.0.0.1) 
+        can both spam the SWServer with registration requests, but neither of their queues
+        starve the other.
+
+        The rest of this change is a lot of support and plumbing for making the above happen.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        
+        * dom/ExceptionData.cpp:
+        (WebCore::ExceptionData::isolatedCopy const):
+        * dom/ExceptionData.h:
+        
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::addRegistration):
+        (WebCore::ServiceWorkerContainer::connectionIdentifier):
+        * workers/service/ServiceWorkerContainer.h:
+        
+        * workers/service/ServiceWorkerJob.cpp:
+        (WebCore::ServiceWorkerJob::ServiceWorkerJob):
+        (WebCore::ServiceWorkerJob::data const): Deleted.
+        * workers/service/ServiceWorkerJob.h:
+        (WebCore::ServiceWorkerJob::create):
+        (WebCore::ServiceWorkerJob::data const):
+        (WebCore::ServiceWorkerJob::createRegisterJob): Deleted.
+        
+        * workers/service/ServiceWorkerJobClient.h:
+        
+        * workers/service/ServiceWorkerJobData.cpp:
+        (WebCore::ServiceWorkerJobData::ServiceWorkerJobData):
+        (WebCore::ServiceWorkerJobData::registrationKey const):
+        (WebCore::ServiceWorkerJobData::isolatedCopy const):
+        * workers/service/ServiceWorkerJobData.h:
+        (WebCore::ServiceWorkerJobData::jobIdentifier const):
+        (WebCore::ServiceWorkerJobData::connectionIdentifier const):
+        (WebCore::ServiceWorkerJobData::encode const):
+        (WebCore::ServiceWorkerJobData::decode):
+
+        * workers/service/ServiceWorkerRegistrationKey.cpp:
+        (WebCore::ServiceWorkerRegistrationKey::emptyKey):
+        (WebCore::ServiceWorkerRegistrationKey::hash const):
+        (WebCore::ServiceWorkerRegistrationKey::operator== const):
+        * workers/service/ServiceWorkerRegistrationKey.h:
+        (WTF::ServiceWorkerRegistrationKeyHash::hash):
+        (WTF::ServiceWorkerRegistrationKeyHash::equal):
+        (WTF::HashTraits<WebCore::ServiceWorkerRegistrationKey>::emptyValue):
+        (WTF::HashTraits<WebCore::ServiceWorkerRegistrationKey>::constructDeletedValue):
+        (WTF::HashTraits<WebCore::ServiceWorkerRegistrationKey>::isDeletedValue):
+
+        * workers/service/ServiceWorkerRegistrationOptions.cpp:
+        (WebCore::RegistrationOptions::isolatedCopy const):
+        * workers/service/ServiceWorkerRegistrationOptions.h:
+        (WebCore::RegistrationOptions::encode const):
+        (WebCore::RegistrationOptions::decode):
+
+        * workers/service/server/SWClientConnection.h:
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::Connection::Connection):
+        (WebCore::SWServer::~SWServer):
+        (WebCore::SWServer::Connection::scheduleJobInServer):
+        (WebCore::SWServer::SWServer):
+        (WebCore::SWServer::scheduleJob):
+        (WebCore::SWServer::rejectJob):
+        (WebCore::SWServer::taskThreadEntryPoint):
+        (WebCore::SWServer::postTask):
+        (WebCore::SWServer::postTaskReply):
+        (WebCore::SWServer::handleTaskRepliesOnMainThread):
+        (WebCore::SWServer::registerConnection):
+        (WebCore::SWServer::unregisterConnection):
+        * workers/service/server/SWServer.h:
+        (WebCore::SWServer::Connection::identifier const):
+
+        * workers/service/server/SWServerRegistration.cpp: Added.
+        (WebCore::SWServerRegistration::SWServerRegistration):
+        (WebCore::SWServerRegistration::~SWServerRegistration):
+        (WebCore::SWServerRegistration::enqueueJob):
+        (WebCore::SWServerRegistration::startNextJob):
+        (WebCore::SWServerRegistration::performCurrentJob):
+        (WebCore::SWServerRegistration::rejectCurrentJob):
+        (WebCore::SWServerRegistration::finishCurrentJob):
+        * workers/service/server/SWServerRegistration.h:
+
 2017-08-25  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         Unreviewed, add comment warning that some flags have been copied into Epiphany
index 5069f7d..41aaee7 100644 (file)
                517A52F11F4754E700DCDC0A /* SWServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A52EF1F47535900DCDC0A /* SWServer.cpp */; };
                517A531C1F4B53B100DCDC0A /* SWClientConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A52FE1F478CCE00DCDC0A /* SWClientConnection.cpp */; };
                517A531D1F4B53B100DCDC0A /* SWClientConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A52FF1F478CCE00DCDC0A /* SWClientConnection.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               517A53251F4B905500DCDC0A /* ServiceWorkerJobData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A53241F4B904A00DCDC0A /* ServiceWorkerJobData.cpp */; };
+               517A53281F4B90B900DCDC0A /* ServiceWorkerRegistrationKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A53271F4B90B200DCDC0A /* ServiceWorkerRegistrationKey.cpp */; };
+               517A53291F4B90B900DCDC0A /* ServiceWorkerRegistrationKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A53261F4B90B200DCDC0A /* ServiceWorkerRegistrationKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
                517A63C31B74318700E7DCDC /* KeyedDecoderCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A63BF1B74317E00E7DCDC /* KeyedDecoderCF.cpp */; };
                517A63C41B74318B00E7DCDC /* KeyedEncoderCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A63C11B74317E00E7DCDC /* KeyedEncoderCF.cpp */; };
                517A63C51B74318F00E7DCDC /* KeyedDecoderCF.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A63C01B74317E00E7DCDC /* KeyedDecoderCF.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51F175661F3EBC8300C74950 /* ServiceWorkerProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F1754E1F3EBC0C00C74950 /* ServiceWorkerProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51F175671F3EBC8300C74950 /* ServiceWorkerRegistration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F1754D1F3EBC0C00C74950 /* ServiceWorkerRegistration.cpp */; };
                51F175681F3EBC8300C74950 /* ServiceWorkerRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F1754C1F3EBC0C00C74950 /* ServiceWorkerRegistration.h */; };
-               51F175691F3EBC8300C74950 /* ServiceWorkerRegistrationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F1754A1F3EBC0C00C74950 /* ServiceWorkerRegistrationOptions.h */; };
-               51F1756A1F3EBC8300C74950 /* ServiceWorkerRegistrationParameters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F175491F3EBC0C00C74950 /* ServiceWorkerRegistrationParameters.cpp */; };
-               51F1756B1F3EBC8300C74950 /* ServiceWorkerRegistrationParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F175481F3EBC0C00C74950 /* ServiceWorkerRegistrationParameters.h */; };
+               51F175691F3EBC8300C74950 /* ServiceWorkerRegistrationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F1754A1F3EBC0C00C74950 /* ServiceWorkerRegistrationOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51F1756C1F3EBC8300C74950 /* ServiceWorkerUpdateViaCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F175471F3EBC0C00C74950 /* ServiceWorkerUpdateViaCache.h */; };
                51F645621F45398F00B54DED /* ExceptionData.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F645601F45398B00B54DED /* ExceptionData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51F645691F4539B900B54DED /* ServiceWorkerJobData.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F645661F45399F00B54DED /* ServiceWorkerJobData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51F6456A1F4539C000B54DED /* ServiceWorkerJobType.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F645651F45399F00B54DED /* ServiceWorkerJobType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               51F645961F4A686F00B54DED /* SWServerRegistration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F645951F4A686100B54DED /* SWServerRegistration.cpp */; };
+               51F645971F4A686F00B54DED /* SWServerRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F645941F4A684F00B54DED /* SWServerRegistration.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               51F645A21F4BF53C00B54DED /* ServiceWorkerRegistrationOptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F645A01F4BF51600B54DED /* ServiceWorkerRegistrationOptions.cpp */; };
+               51F645A41F4C001700B54DED /* ExceptionData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F645A31F4C000C00B54DED /* ExceptionData.cpp */; };
                51F798EF1BE880E7008AE491 /* IDBIndexInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F798EB1BE880D3008AE491 /* IDBIndexInfo.cpp */; };
                51F798F01BE880E7008AE491 /* IDBIndexInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F798EC1BE880D3008AE491 /* IDBIndexInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51F886C01F32923100C193EF /* JSNavigatorServiceWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F886BF1F32920700C193EF /* JSNavigatorServiceWorker.h */; };
                517A52EF1F47535900DCDC0A /* SWServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SWServer.cpp; sourceTree = "<group>"; };
                517A52FE1F478CCE00DCDC0A /* SWClientConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SWClientConnection.cpp; sourceTree = "<group>"; };
                517A52FF1F478CCE00DCDC0A /* SWClientConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWClientConnection.h; sourceTree = "<group>"; };
+               517A53241F4B904A00DCDC0A /* ServiceWorkerJobData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerJobData.cpp; sourceTree = "<group>"; };
+               517A53261F4B90B200DCDC0A /* ServiceWorkerRegistrationKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerRegistrationKey.h; sourceTree = "<group>"; };
+               517A53271F4B90B200DCDC0A /* ServiceWorkerRegistrationKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerRegistrationKey.cpp; sourceTree = "<group>"; };
                517A63BF1B74317E00E7DCDC /* KeyedDecoderCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyedDecoderCF.cpp; sourceTree = "<group>"; };
                517A63C01B74317E00E7DCDC /* KeyedDecoderCF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyedDecoderCF.h; sourceTree = "<group>"; };
                517A63C11B74317E00E7DCDC /* KeyedEncoderCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyedEncoderCF.cpp; sourceTree = "<group>"; };
                51F175051F358BDE00C74950 /* JSWorkerType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWorkerType.h; sourceTree = "<group>"; };
                51F175461F3EBC0C00C74950 /* ServiceWorkerUpdateViaCache.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ServiceWorkerUpdateViaCache.idl; sourceTree = "<group>"; };
                51F175471F3EBC0C00C74950 /* ServiceWorkerUpdateViaCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerUpdateViaCache.h; sourceTree = "<group>"; };
-               51F175481F3EBC0C00C74950 /* ServiceWorkerRegistrationParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerRegistrationParameters.h; sourceTree = "<group>"; };
-               51F175491F3EBC0C00C74950 /* ServiceWorkerRegistrationParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerRegistrationParameters.cpp; sourceTree = "<group>"; };
                51F1754A1F3EBC0C00C74950 /* ServiceWorkerRegistrationOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerRegistrationOptions.h; sourceTree = "<group>"; };
                51F1754B1F3EBC0C00C74950 /* ServiceWorkerRegistration.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ServiceWorkerRegistration.idl; sourceTree = "<group>"; };
                51F1754C1F3EBC0C00C74950 /* ServiceWorkerRegistration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerRegistration.h; sourceTree = "<group>"; };
                51F645601F45398B00B54DED /* ExceptionData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionData.h; sourceTree = "<group>"; };
                51F645651F45399F00B54DED /* ServiceWorkerJobType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerJobType.h; sourceTree = "<group>"; };
                51F645661F45399F00B54DED /* ServiceWorkerJobData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerJobData.h; sourceTree = "<group>"; };
+               51F645941F4A684F00B54DED /* SWServerRegistration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWServerRegistration.h; sourceTree = "<group>"; };
+               51F645951F4A686100B54DED /* SWServerRegistration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SWServerRegistration.cpp; sourceTree = "<group>"; };
+               51F645A01F4BF51600B54DED /* ServiceWorkerRegistrationOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerRegistrationOptions.cpp; sourceTree = "<group>"; };
+               51F645A31F4C000C00B54DED /* ExceptionData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionData.cpp; sourceTree = "<group>"; };
                51F6A3D50663BF04004D2919 /* HTMLCanvasElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLCanvasElement.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                51F6A3D60663BF04004D2919 /* HTMLCanvasElement.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HTMLCanvasElement.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                51F798EB1BE880D3008AE491 /* IDBIndexInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBIndexInfo.cpp; sourceTree = "<group>"; };
                                517A52FF1F478CCE00DCDC0A /* SWClientConnection.h */,
                                517A52EF1F47535900DCDC0A /* SWServer.cpp */,
                                517A52EE1F47535900DCDC0A /* SWServer.h */,
+                               51F645951F4A686100B54DED /* SWServerRegistration.cpp */,
+                               51F645941F4A684F00B54DED /* SWServerRegistration.h */,
                        );
                        path = server;
                        sourceTree = "<group>";
                                51F175521F3EBC0C00C74950 /* ServiceWorkerJob.cpp */,
                                51F175511F3EBC0C00C74950 /* ServiceWorkerJob.h */,
                                51F175501F3EBC0C00C74950 /* ServiceWorkerJobClient.h */,
+                               517A53241F4B904A00DCDC0A /* ServiceWorkerJobData.cpp */,
                                51F645661F45399F00B54DED /* ServiceWorkerJobData.h */,
                                51F645651F45399F00B54DED /* ServiceWorkerJobType.h */,
                                51F1754F1F3EBC0C00C74950 /* ServiceWorkerProvider.cpp */,
                                51F1754D1F3EBC0C00C74950 /* ServiceWorkerRegistration.cpp */,
                                51F1754C1F3EBC0C00C74950 /* ServiceWorkerRegistration.h */,
                                51F1754B1F3EBC0C00C74950 /* ServiceWorkerRegistration.idl */,
+                               517A53271F4B90B200DCDC0A /* ServiceWorkerRegistrationKey.cpp */,
+                               517A53261F4B90B200DCDC0A /* ServiceWorkerRegistrationKey.h */,
+                               51F645A01F4BF51600B54DED /* ServiceWorkerRegistrationOptions.cpp */,
                                51F1754A1F3EBC0C00C74950 /* ServiceWorkerRegistrationOptions.h */,
-                               51F175491F3EBC0C00C74950 /* ServiceWorkerRegistrationParameters.cpp */,
-                               51F175481F3EBC0C00C74950 /* ServiceWorkerRegistrationParameters.h */,
                                51F175471F3EBC0C00C74950 /* ServiceWorkerUpdateViaCache.h */,
                                51F175461F3EBC0C00C74950 /* ServiceWorkerUpdateViaCache.idl */,
                        );
                                CDCE5CD014633BC900D47CCA /* EventTargetFactory.in */,
                                93D196321D6CAB8200FC7E47 /* Exception.h */,
                                935FBCF109BA143B00E230B1 /* ExceptionCode.h */,
+                               51F645A31F4C000C00B54DED /* ExceptionData.cpp */,
                                51F645601F45398B00B54DED /* ExceptionData.h */,
                                93D196301D6CAB7600FC7E47 /* ExceptionOr.h */,
                                E47E276716036EDC00EE2AFB /* ExtensionStyleSheets.cpp */,
                                51F6456A1F4539C000B54DED /* ServiceWorkerJobType.h in Headers */,
                                51F175661F3EBC8300C74950 /* ServiceWorkerProvider.h in Headers */,
                                51F175681F3EBC8300C74950 /* ServiceWorkerRegistration.h in Headers */,
+                               517A53291F4B90B900DCDC0A /* ServiceWorkerRegistrationKey.h in Headers */,
                                51F175691F3EBC8300C74950 /* ServiceWorkerRegistrationOptions.h in Headers */,
-                               51F1756B1F3EBC8300C74950 /* ServiceWorkerRegistrationParameters.h in Headers */,
                                51F1756C1F3EBC8300C74950 /* ServiceWorkerUpdateViaCache.h in Headers */,
                                93309E10099E64920056E581 /* SetNodeAttributeCommand.h in Headers */,
                                B8DBDB4C130B0F8A00F5CDB1 /* SetSelectionCommand.h in Headers */,
                                B2E4EC980D00C22B00432643 /* SVGZoomEvent.h in Headers */,
                                517A531D1F4B53B100DCDC0A /* SWClientConnection.h in Headers */,
                                517A52F01F47535B00DCDC0A /* SWServer.h in Headers */,
+                               51F645971F4A686F00B54DED /* SWServerRegistration.h in Headers */,
                                E180811716FCF9CB00B80D07 /* SynchronousLoaderClient.h in Headers */,
                                26FAE4CF1852E3A5004C8C46 /* SynchronousResourceHandleCFURLConnectionDelegate.h in Headers */,
                                0F03C0741884695E00A5F8CA /* SystemMemory.h in Headers */,
                                E0FEF372B27C53EAC1C1FBEE /* EventSource.cpp in Sources */,
                                E12EDBEA0B308E0B002704B6 /* EventTarget.cpp in Sources */,
                                262EC41D1D110B9000BA78FC /* EventTrackingRegions.cpp in Sources */,
+                               51F645A41F4C001700B54DED /* ExceptionData.cpp in Sources */,
                                724ED32C1A3A7E5400F5F13C /* EXTBlendMinMax.cpp in Sources */,
                                31DCDF431DA1C45400EA5B93 /* ExtendedColor.cpp in Sources */,
                                6E67D2A61280E8A4008758F7 /* Extensions3DOpenGL.cpp in Sources */,
                                51F1755E1F3EBC8300C74950 /* ServiceWorkerContainer.cpp in Sources */,
                                51F175601F3EBC8300C74950 /* ServiceWorkerGlobalScope.cpp in Sources */,
                                51F175621F3EBC8300C74950 /* ServiceWorkerJob.cpp in Sources */,
+                               517A53251F4B905500DCDC0A /* ServiceWorkerJobData.cpp in Sources */,
                                51F175651F3EBC8300C74950 /* ServiceWorkerProvider.cpp in Sources */,
                                51F175671F3EBC8300C74950 /* ServiceWorkerRegistration.cpp in Sources */,
-                               51F1756A1F3EBC8300C74950 /* ServiceWorkerRegistrationParameters.cpp in Sources */,
+                               517A53281F4B90B900DCDC0A /* ServiceWorkerRegistrationKey.cpp in Sources */,
+                               51F645A21F4BF53C00B54DED /* ServiceWorkerRegistrationOptions.cpp in Sources */,
                                93309E0F099E64920056E581 /* SetNodeAttributeCommand.cpp in Sources */,
                                B8DBDB4B130B0F8A00F5CDB1 /* SetSelectionCommand.cpp in Sources */,
                                14C9A5EA0B3D105F005A0232 /* Settings.cpp in Sources */,
                                B2E4EC970D00C22B00432643 /* SVGZoomEvent.cpp in Sources */,
                                517A531C1F4B53B100DCDC0A /* SWClientConnection.cpp in Sources */,
                                517A52F11F4754E700DCDC0A /* SWServer.cpp in Sources */,
+                               51F645961F4A686F00B54DED /* SWServerRegistration.cpp in Sources */,
                                E180811216FCF42F00B80D07 /* SynchronousLoaderClient.cpp in Sources */,
                                E180811616FCF9CB00B80D07 /* SynchronousLoaderClient.mm in Sources */,
                                442ABCD617D9262F00D30715 /* SynchronousLoaderClientCFNet.cpp in Sources */,
  */
 
 #include "config.h"
-#include "ServiceWorkerRegistrationParameters.h"
-
-#if ENABLE(SERVICE_WORKER)
+#include "ExceptionData.h"
 
 namespace WebCore {
 
-} // namespace WebCore
+ExceptionData ExceptionData::isolatedCopy() const
+{
+    ExceptionData result;
+    result.code = code;
+    result.message = message.isolatedCopy();
 
-#endif // ENABLE(SERVICE_WORKER)
+    return result;
+}
+
+} // namespace WebCore
index 8e7e72e..265bccc 100644 (file)
@@ -34,6 +34,8 @@ struct ExceptionData {
     ExceptionCode code;
     String message;
 
+    ExceptionData isolatedCopy() const;
+
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static bool decode(Decoder&, ExceptionData&);
 
index 5d747fe..af266e7 100644 (file)
@@ -34,8 +34,8 @@
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
 #include "ServiceWorkerJob.h"
+#include "ServiceWorkerJobData.h"
 #include "ServiceWorkerProvider.h"
-#include "ServiceWorkerRegistrationParameters.h"
 #include "URL.h"
 #include <wtf/RunLoop.h>
 
@@ -88,20 +88,21 @@ void ServiceWorkerContainer::addRegistration(const String& relativeScriptURL, co
         return;
     }
 
-    ServiceWorkerRegistrationParameters parameters;
-    parameters.scriptURL = context->completeURL(relativeScriptURL);
-    if (!parameters.scriptURL.isValid()) {
+    ServiceWorkerJobData jobData(m_swConnection->identifier());
+
+    jobData.scriptURL = context->completeURL(relativeScriptURL);
+    if (!jobData.scriptURL.isValid()) {
         promise->reject(Exception { TypeError, ASCIILiteral("serviceWorker.register() must be called with a valid relative script URL") });
         return;
     }
 
     // FIXME: The spec disallows scripts outside of HTTP(S), but we'll likely support app custom URL schemes in WebKit.
-    if (!parameters.scriptURL.protocolIsInHTTPFamily()) {
+    if (!jobData.scriptURL.protocolIsInHTTPFamily()) {
         promise->reject(Exception { TypeError, ASCIILiteral("serviceWorker.register() must be called with a script URL whose protocol is either HTTP or HTTPS") });
         return;
     }
 
-    String path = parameters.scriptURL.path();
+    String path = jobData.scriptURL.path();
     if (path.containsIgnoringASCIICase("%2f") || path.containsIgnoringASCIICase("%5c")) {
         promise->reject(Exception { TypeError, ASCIILiteral("serviceWorker.register() must be called with a script URL whose path does not contain '%%2f' or '%%5c'") });
         return;
@@ -109,13 +110,14 @@ void ServiceWorkerContainer::addRegistration(const String& relativeScriptURL, co
 
     String scope = options.scope.isEmpty() ? ASCIILiteral("./") : options.scope;
     if (!scope.isEmpty())
-        parameters.scopeURL = context->completeURL(scope);
+        jobData.scopeURL = context->completeURL(scope);
 
-    parameters.clientCreationURL = context->url();
-    parameters.topOrigin = SecurityOriginData::fromSecurityOrigin(context->topOrigin());
-    parameters.options = options;
+    jobData.clientCreationURL = context->url();
+    jobData.topOrigin = SecurityOriginData::fromSecurityOrigin(context->topOrigin());
+    jobData.type = ServiceWorkerJobType::Register;
+    jobData.registrationOptions = std::make_unique<RegistrationOptions>(options);
 
-    scheduleJob(ServiceWorkerJob::createRegisterJob(*this, WTFMove(promise), WTFMove(parameters)));
+    scheduleJob(ServiceWorkerJob::create(*this, WTFMove(promise), WTFMove(jobData)));
 }
 
 void ServiceWorkerContainer::scheduleJob(Ref<ServiceWorkerJob>&& job)
@@ -149,6 +151,12 @@ void ServiceWorkerContainer::jobDidFinish(ServiceWorkerJob& job)
     ASSERT_UNUSED(taken, taken.get() == &job);
 }
 
+uint64_t ServiceWorkerContainer::connectionIdentifier()
+{
+    ASSERT(m_swConnection);
+    return m_swConnection->identifier();
+}
+
 const char* ServiceWorkerContainer::activeDOMObjectName() const
 {
     return "ServiceWorkerContainer";
index 9caea7c..d9c4dc7 100644 (file)
@@ -71,6 +71,7 @@ public:
 private:
     void scheduleJob(Ref<ServiceWorkerJob>&&);
     void jobDidFinish(ServiceWorkerJob&) final;
+    uint64_t connectionIdentifier() final;
 
     const char* activeDOMObjectName() const final;
     bool canSuspendForDocumentSuspension() const final;
index c8fa697..4505a77 100644 (file)
 
 #include "JSDOMPromiseDeferred.h"
 #include "ServiceWorkerJobData.h"
-#include "ServiceWorkerRegistrationParameters.h"
 
 namespace WebCore {
 
 static std::atomic<uint64_t> currentIdentifier;
 
-ServiceWorkerJob::ServiceWorkerJob(ServiceWorkerJobClient& client, Ref<DeferredPromise>&& promise, ServiceWorkerRegistrationParameters&& parameters)
+ServiceWorkerJob::ServiceWorkerJob(ServiceWorkerJobClient& client, Ref<DeferredPromise>&& promise, ServiceWorkerJobData&& jobData)
     : m_client(client)
+    , m_jobData(WTFMove(jobData))
     , m_promise(WTFMove(promise))
     , m_identifier(++currentIdentifier)
 {
-    m_registrationParameters = std::make_unique<ServiceWorkerRegistrationParameters>(WTFMove(parameters));
 }
 
 ServiceWorkerJob::~ServiceWorkerJob()
@@ -61,11 +60,6 @@ void ServiceWorkerJob::failedWithException(const Exception& exception)
     m_client->jobDidFinish(*this);
 }
 
-ServiceWorkerJobData ServiceWorkerJob::data() const
-{
-    return { m_identifier, m_type };
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index dfe0abf..ea80b37 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "ServiceWorkerJobClient.h"
+#include "ServiceWorkerJobData.h"
 #include <wtf/RefPtr.h>
 #include <wtf/RunLoop.h>
 #include <wtf/ThreadSafeRefCounted.h>
@@ -38,14 +39,12 @@ namespace WebCore {
 class DeferredPromise;
 class Exception;
 enum class ServiceWorkerJobType;
-struct ServiceWorkerJobData;
-struct ServiceWorkerRegistrationParameters;
 
 class ServiceWorkerJob : public ThreadSafeRefCounted<ServiceWorkerJob> {
 public:
-    static Ref<ServiceWorkerJob> createRegisterJob(ServiceWorkerJobClient& client, Ref<DeferredPromise>&& promise, ServiceWorkerRegistrationParameters&& parameters)
+    static Ref<ServiceWorkerJob> create(ServiceWorkerJobClient& client, Ref<DeferredPromise>&& promise, ServiceWorkerJobData&& jobData)
     {
-        return adoptRef(*new ServiceWorkerJob(client, WTFMove(promise), WTFMove(parameters)));
+        return adoptRef(*new ServiceWorkerJob(client, WTFMove(promise), WTFMove(jobData)));
     }
 
     WEBCORE_EXPORT ~ServiceWorkerJob();
@@ -54,20 +53,18 @@ public:
 
     uint64_t identifier() const { return m_identifier; }
 
-    ServiceWorkerJobData data() const;
+    ServiceWorkerJobData data() const { return m_jobData; }
 
 private:
-    ServiceWorkerJob(ServiceWorkerJobClient&, Ref<DeferredPromise>&&, ServiceWorkerRegistrationParameters&&);
+    ServiceWorkerJob(ServiceWorkerJobClient&, Ref<DeferredPromise>&&, ServiceWorkerJobData&&);
 
     Ref<ServiceWorkerJobClient> m_client;
-    std::unique_ptr<ServiceWorkerRegistrationParameters> m_registrationParameters;
+    ServiceWorkerJobData m_jobData;
     Ref<DeferredPromise> m_promise;
 
     bool m_completed { false };
     uint64_t m_identifier;
 
-    ServiceWorkerJobType m_type;
-
     Ref<RunLoop> m_runLoop { RunLoop::current() };
 
 #if !ASSERT_DISABLED
index 239e849..20c0219 100644 (file)
@@ -36,6 +36,7 @@ public:
     virtual ~ServiceWorkerJobClient() { };
 
     virtual void jobDidFinish(ServiceWorkerJob&) = 0;
+    virtual uint64_t connectionIdentifier() = 0;
 
     virtual void ref() = 0;
     virtual void deref() = 0;
diff --git a/Source/WebCore/workers/service/ServiceWorkerJobData.cpp b/Source/WebCore/workers/service/ServiceWorkerJobData.cpp
new file mode 100644 (file)
index 0000000..8722cc3
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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 "ServiceWorkerJobData.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+namespace WebCore {
+
+static std::atomic<uint64_t> currentJobIdentifier;
+
+ServiceWorkerJobData::ServiceWorkerJobData(uint64_t connectionIdentifier)
+    : m_jobIdentifier(++currentJobIdentifier)
+    , m_connectionIdentifier(connectionIdentifier)
+{
+}
+
+ServiceWorkerJobData::ServiceWorkerJobData(const ServiceWorkerJobData& other)
+{
+    m_jobIdentifier = other.m_jobIdentifier;
+    m_connectionIdentifier = other.m_connectionIdentifier;
+    scriptURL = other.scriptURL;
+    clientCreationURL = other.clientCreationURL;
+    topOrigin = other.topOrigin;
+    scopeURL = other.scopeURL;
+    type = other.type;
+
+    if (other.registrationOptions)
+        registrationOptions = std::make_unique<RegistrationOptions>(*other.registrationOptions);
+}
+
+ServiceWorkerRegistrationKey ServiceWorkerJobData::registrationKey() const
+{
+    return { clientCreationURL, topOrigin };
+}
+
+ServiceWorkerJobData ServiceWorkerJobData::isolatedCopy() const
+{
+    ServiceWorkerJobData result;
+    result.m_jobIdentifier = m_jobIdentifier;
+    result.m_connectionIdentifier = m_connectionIdentifier;
+    result.type = type;
+
+    result.scriptURL = scriptURL.isolatedCopy();
+    result.clientCreationURL = clientCreationURL.isolatedCopy();
+    result.topOrigin = topOrigin.isolatedCopy();
+    result.scopeURL = scopeURL.isolatedCopy();
+
+    if (registrationOptions)
+        result.registrationOptions = std::make_unique<RegistrationOptions>(registrationOptions->isolatedCopy());
+    return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
index a9e1cbe..12af2d6 100644 (file)
 
 #if ENABLE(SERVICE_WORKER)
 
-namespace WebCore {
+#include "SecurityOriginData.h"
+#include "ServiceWorkerJobType.h"
+#include "ServiceWorkerRegistrationKey.h"
+#include "ServiceWorkerRegistrationOptions.h"
+#include "URL.h"
 
-enum class ServiceWorkerJobType;
+namespace WebCore {
 
 struct ServiceWorkerJobData {
-    uint64_t identifier;
+public:
+    explicit ServiceWorkerJobData(uint64_t connectionIdentifier);
+    ServiceWorkerJobData(const ServiceWorkerJobData&);
+    ServiceWorkerJobData() = default;
+
+    uint64_t jobIdentifier() const { return m_jobIdentifier; }
+    uint64_t connectionIdentifier() const { return m_connectionIdentifier; }
+
+    URL scriptURL;
+    URL clientCreationURL;
+    SecurityOriginData topOrigin;
+    URL scopeURL;
     ServiceWorkerJobType type;
 
+    std::unique_ptr<RegistrationOptions> registrationOptions;
+
+    ServiceWorkerRegistrationKey registrationKey() const;
+    ServiceWorkerJobData isolatedCopy() const;
+
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static bool decode(Decoder&, ServiceWorkerJobData&);
+
+private:
+    uint64_t m_jobIdentifier { 0 };
+    uint64_t m_connectionIdentifier { 0 };
 };
 
 template<class Encoder>
 void ServiceWorkerJobData::encode(Encoder& encoder) const
 {
-    encoder << identifier;
+    encoder << m_jobIdentifier << m_connectionIdentifier << scriptURL << clientCreationURL << topOrigin << scopeURL;
     encoder.encodeEnum(type);
+    switch (type) {
+    case ServiceWorkerJobType::Register:
+        RELEASE_ASSERT(registrationOptions);
+        encoder << *registrationOptions;
+        break;
+    }
 }
 
 template<class Decoder>
 bool ServiceWorkerJobData::decode(Decoder& decoder, ServiceWorkerJobData& jobData)
 {
-    if (!decoder.decode(jobData.identifier))
+    if (!decoder.decode(jobData.m_jobIdentifier))
+        return false;
+    if (!decoder.decode(jobData.m_connectionIdentifier))
+        return false;
+    if (!decoder.decode(jobData.scriptURL))
+        return false;
+    if (!decoder.decode(jobData.clientCreationURL))
+        return false;
+    if (!decoder.decode(jobData.topOrigin))
+        return false;
+    if (!decoder.decode(jobData.scopeURL))
         return false;
     if (!decoder.decodeEnum(jobData.type))
         return false;
 
+    switch (jobData.type) {
+    case ServiceWorkerJobType::Register:
+        jobData.registrationOptions = std::make_unique<RegistrationOptions>();
+        if (!decoder.decode(*jobData.registrationOptions))
+            return false;
+        break;
+    }
+
     return true;
 }
 
diff --git a/Source/WebCore/workers/service/ServiceWorkerRegistrationKey.cpp b/Source/WebCore/workers/service/ServiceWorkerRegistrationKey.cpp
new file mode 100644 (file)
index 0000000..5c01178
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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 "ServiceWorkerRegistrationKey.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "URLHash.h"
+
+namespace WebCore {
+
+ServiceWorkerRegistrationKey ServiceWorkerRegistrationKey::emptyKey()
+{
+    return { };
+}
+
+unsigned ServiceWorkerRegistrationKey::hash() const
+{
+    unsigned hashes[2];
+    hashes[0] = URLHash::hash(clientCreationURL);
+    hashes[1] = SecurityOriginDataHash::hash(topOrigin);
+
+    return StringHasher::hashMemory(hashes, sizeof(hashes));
+}
+
+bool ServiceWorkerRegistrationKey::operator==(const ServiceWorkerRegistrationKey& other) const
+{
+    return clientCreationURL == other.clientCreationURL && topOrigin == other.topOrigin;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
diff --git a/Source/WebCore/workers/service/ServiceWorkerRegistrationKey.h b/Source/WebCore/workers/service/ServiceWorkerRegistrationKey.h
new file mode 100644 (file)
index 0000000..ba97c6c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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 "SecurityOriginData.h"
+#include "URL.h"
+
+namespace WebCore {
+
+struct ServiceWorkerRegistrationKey {
+    URL clientCreationURL;
+    SecurityOriginData topOrigin;
+
+    static ServiceWorkerRegistrationKey emptyKey();
+    unsigned hash() const;
+
+    bool operator==(const ServiceWorkerRegistrationKey&) const;
+};
+
+} // namespace WebCore
+
+namespace WTF {
+
+struct ServiceWorkerRegistrationKeyHash {
+    static unsigned hash(const WebCore::ServiceWorkerRegistrationKey& key) { return key.hash(); }
+    static bool equal(const WebCore::ServiceWorkerRegistrationKey& a, const WebCore::ServiceWorkerRegistrationKey& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+template<> struct HashTraits<WebCore::ServiceWorkerRegistrationKey> : GenericHashTraits<WebCore::ServiceWorkerRegistrationKey> {
+    static WebCore::ServiceWorkerRegistrationKey emptyValue() { return WebCore::ServiceWorkerRegistrationKey::emptyKey(); }
+
+    static void constructDeletedValue(WebCore::ServiceWorkerRegistrationKey& slot) { slot.clientCreationURL = WebCore::URL(HashTableDeletedValue); }
+    static bool isDeletedValue(const WebCore::ServiceWorkerRegistrationKey& slot) { return slot.clientCreationURL.isHashTableDeletedValue(); }
+};
+
+template<> struct DefaultHash<WebCore::ServiceWorkerRegistrationKey> {
+    typedef ServiceWorkerRegistrationKeyHash Hash;
+};
+
+} // namespace WTF
+
+#endif // ENABLE(SERVICE_WORKER)
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#pragma once
+#include "config.h"
+#include "ServiceWorkerRegistrationOptions.h"
 
 #if ENABLE(SERVICE_WORKER)
 
-#include "SecurityOriginData.h"
-#include "ServiceWorkerRegistrationOptions.h"
-#include "URL.h"
-#include <pal/SessionID.h>
-
 namespace WebCore {
 
-struct ServiceWorkerRegistrationParameters {
-    URL scriptURL;
-    URL clientCreationURL;
-    SecurityOriginData topOrigin;
-    URL scopeURL;
-    RegistrationOptions options;
-};
+RegistrationOptions RegistrationOptions::isolatedCopy() const
+{
+    RegistrationOptions result;
+    result.scope = scope.isolatedCopy();
+    result.type = type;
+    result.updateViaCache = updateViaCache;
+
+    return result;
+}
 
 } // namespace WebCore
 
index d4799e5..187b85b 100644 (file)
@@ -38,8 +38,34 @@ struct RegistrationOptions {
     String scope;
     WorkerType type;
     ServiceWorkerUpdateViaCache updateViaCache;
+
+    RegistrationOptions isolatedCopy() const;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static bool decode(Decoder&, RegistrationOptions&);
 };
 
+template<class Encoder>
+void RegistrationOptions::encode(Encoder& encoder) const
+{
+    encoder << scope;
+    encoder.encodeEnum(type);
+    encoder.encodeEnum(updateViaCache);
+}
+
+template<class Decoder>
+bool RegistrationOptions::decode(Decoder& decoder, RegistrationOptions& options)
+{
+    if (!decoder.decode(options.scope))
+        return false;
+    if (!decoder.decodeEnum(options.type))
+        return false;
+    if (!decoder.decodeEnum(options.updateViaCache))
+        return false;
+
+    return true;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index c648e47..9684440 100644 (file)
@@ -42,6 +42,8 @@ public:
 
     void scheduleJob(ServiceWorkerJob&);
 
+    virtual uint64_t identifier() const = 0;
+
 protected:
     WEBCORE_EXPORT void jobRejectedInServer(uint64_t jobIdentifier, const ExceptionData&);
 
index 2f1a392..a4f35a5 100644 (file)
 #include "ExceptionCode.h"
 #include "ExceptionData.h"
 #include "Logging.h"
+#include "SWServerRegistration.h"
 #include "ServiceWorkerJobData.h"
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
-SWServer::Connection::Connection(SWServer& server)
+SWServer::Connection::Connection(SWServer& server, uint64_t identifier)
     : m_server(server)
+    , m_identifier(identifier)
 {
     m_server.registerConnection(*this);
 }
@@ -47,34 +49,108 @@ SWServer::Connection::~Connection()
     m_server.unregisterConnection(*this);
 }
 
-
 SWServer::~SWServer()
 {
     RELEASE_ASSERT(m_connections.isEmpty());
+    RELEASE_ASSERT(m_registrations.isEmpty());
+
+    // For a SWServer to be cleanly shut down its thread must have finished and gone away.
+    // At this stage in development of the feature that actually never happens.
+    // But once it does start happening, this ASSERT will catch us doing it wrong.
+    Locker<Lock> locker(m_taskThreadLock);
+    ASSERT(!m_taskThread);
 }
 
 void SWServer::Connection::scheduleJobInServer(const ServiceWorkerJobData& jobData)
 {
-    LOG(ServiceWorker, "Scheduling ServiceWorker job %" PRIu64 " in server", jobData.identifier);
-    m_server.scheduleJob(*this, jobData);
+    LOG(ServiceWorker, "Scheduling ServiceWorker job %" PRIu64 "-%" PRIu64 " in server", jobData.connectionIdentifier(), jobData.jobIdentifier());
+    ASSERT(identifier() == jobData.connectionIdentifier());
+
+    m_server.scheduleJob(jobData);
+}
+
+SWServer::SWServer()
+{
+    m_taskThread = Thread::create(ASCIILiteral("ServiceWorker Task Thread"), [this] {
+        taskThreadEntryPoint();
+    });
+}
+
+void SWServer::scheduleJob(const ServiceWorkerJobData& jobData)
+{
+    ASSERT(m_connections.contains(jobData.connectionIdentifier()));
+
+    auto result = m_registrations.add(jobData.registrationKey(), nullptr);
+    if (result.isNewEntry)
+        result.iterator->value = std::make_unique<SWServerRegistration>(*this);
+
+    ASSERT(result.iterator->value);
+
+    result.iterator->value->enqueueJob(jobData);
+}
+
+void SWServer::rejectJob(const ServiceWorkerJobData& jobData, const ExceptionData& exceptionData)
+{
+    LOG(ServiceWorker, "Rejected ServiceWorker job %" PRIu64 "-%" PRIu64 " in server", jobData.connectionIdentifier(), jobData.jobIdentifier());
+    auto* connection = m_connections.get(jobData.connectionIdentifier());
+    if (!connection)
+        return;
+
+    connection->rejectJobInClient(jobData.jobIdentifier(), exceptionData);
+}
+
+void SWServer::taskThreadEntryPoint()
+{
+    ASSERT(!isMainThread());
+
+    while (!m_taskQueue.isKilled())
+        m_taskQueue.waitForMessage().performTask();
+
+    Locker<Lock> locker(m_taskThreadLock);
+    m_taskThread = nullptr;
 }
 
-void SWServer::scheduleJob(Connection& connection, const ServiceWorkerJobData& jobData)
+void SWServer::postTask(CrossThreadTask&& task)
 {
-    // FIXME: For now, all scheduled jobs immediately reject.
-    connection.rejectJobInClient(jobData.identifier, ExceptionData { UnknownError, ASCIILiteral("serviceWorker job scheduling is not yet implemented") });
+    m_taskQueue.append(WTFMove(task));
+}
+
+void SWServer::postTaskReply(CrossThreadTask&& task)
+{
+    m_taskReplyQueue.append(WTFMove(task));
+
+    Locker<Lock> locker(m_mainThreadReplyLock);
+    if (m_mainThreadReplyScheduled)
+        return;
+
+    m_mainThreadReplyScheduled = true;
+    callOnMainThread([this] {
+        handleTaskRepliesOnMainThread();
+    });
+}
+
+void SWServer::handleTaskRepliesOnMainThread()
+{
+    {
+        Locker<Lock> locker(m_mainThreadReplyLock);
+        m_mainThreadReplyScheduled = false;
+    }
+
+    while (auto task = m_taskReplyQueue.tryGetMessage())
+        task->performTask();
 }
 
 void SWServer::registerConnection(Connection& connection)
 {
-    auto result = m_connections.add(&connection);
-    ASSERT_UNUSED(result, result.isNewEntry);
+    auto result = m_connections.add(connection.identifier(), nullptr);
+    ASSERT(result.isNewEntry);
+    result.iterator->value = &connection;
 }
 
 void SWServer::unregisterConnection(Connection& connection)
 {
-    ASSERT(m_connections.contains(&connection));
-    m_connections.remove(&connection);
+    ASSERT(m_connections.get(connection.identifier()) == &connection);
+    m_connections.remove(connection.identifier());
 }
 
 } // namespace WebCore
index 1ee9779..31ef97e 100644 (file)
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "SWServerRegistration.h"
 #include "ServiceWorkerJob.h"
+#include "ServiceWorkerRegistrationKey.h"
+#include <wtf/CrossThreadQueue.h>
+#include <wtf/CrossThreadTask.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
+#include <wtf/RunLoop.h>
 #include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Threading.h>
 
 namespace WebCore {
 
+class SWServerRegistration;
 struct ExceptionData;
 
 class SWServer {
@@ -43,8 +50,10 @@ public:
     public:
         WEBCORE_EXPORT virtual ~Connection();
 
+        uint64_t identifier() const { return m_identifier; };
+
     protected:
-        WEBCORE_EXPORT Connection(SWServer&);
+        WEBCORE_EXPORT Connection(SWServer&, uint64_t identifier);
         SWServer& server() { return m_server; }
 
         WEBCORE_EXPORT void scheduleJobInServer(const ServiceWorkerJobData&);
@@ -53,17 +62,36 @@ public:
         virtual void rejectJobInClient(uint64_t jobIdentifier, const ExceptionData&) = 0;
 
         SWServer& m_server;
+        uint64_t m_identifier;
     };
 
+    WEBCORE_EXPORT SWServer();
     WEBCORE_EXPORT ~SWServer();
 
-    WEBCORE_EXPORT void scheduleJob(Connection&, const ServiceWorkerJobData&);
+    void scheduleJob(const ServiceWorkerJobData&);
+    void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
+
+    void postTask(CrossThreadTask&&);
+    void postTaskReply(CrossThreadTask&&);
 
 private:
     void registerConnection(Connection&);
     void unregisterConnection(Connection&);
 
-    HashSet<Connection*> m_connections;
+    void taskThreadEntryPoint();
+    void handleTaskRepliesOnMainThread();
+
+    HashMap<uint64_t, Connection*> m_connections;
+    HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations;
+
+    RefPtr<Thread> m_taskThread;
+    Lock m_taskThreadLock;
+
+    CrossThreadQueue<CrossThreadTask> m_taskQueue;
+    CrossThreadQueue<CrossThreadTask> m_taskReplyQueue;
+
+    Lock m_mainThreadReplyLock;
+    bool m_mainThreadReplyScheduled { false };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/workers/service/server/SWServerRegistration.cpp b/Source/WebCore/workers/service/server/SWServerRegistration.cpp
new file mode 100644 (file)
index 0000000..4fd4076
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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 "SWServerRegistration.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "ExceptionData.h"
+#include "SWServer.h"
+
+namespace WebCore {
+
+SWServerRegistration::SWServerRegistration(SWServer& server)
+    : m_jobTimer(*this, &SWServerRegistration::startNextJob)
+    , m_server(server)
+{
+}
+
+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::startNextJob()
+{
+    ASSERT(isMainThread());
+    ASSERT(!m_currentJob);
+    ASSERT(!m_jobQueue.isEmpty());
+
+    m_currentJob = std::make_unique<ServiceWorkerJobData>(m_jobQueue.takeFirst().isolatedCopy());
+    m_server.postTask(createCrossThreadTask(*this, &SWServerRegistration::performCurrentJob));
+}
+
+void SWServerRegistration::performCurrentJob()
+{
+    ASSERT(!isMainThread());
+
+    auto exception = ExceptionData { UnknownError, ASCIILiteral("serviceWorker job scheduling is not yet implemented") };
+    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::rejectCurrentJob, exception));
+}
+
+void SWServerRegistration::rejectCurrentJob(const ExceptionData& exceptionData)
+{
+    ASSERT(isMainThread());
+    ASSERT(m_currentJob);
+
+    m_server.rejectJob(*m_currentJob, exceptionData);
+
+    finishCurrentJob();
+}
+
+void SWServerRegistration::finishCurrentJob()
+{
+    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/SWServerRegistration.h b/Source/WebCore/workers/service/server/SWServerRegistration.h
new file mode 100644 (file)
index 0000000..d4a3300
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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 "ServiceWorkerJobData.h"
+#include "Timer.h"
+#include <wtf/Deque.h>
+
+namespace WebCore {
+
+class SWServer;
+struct ExceptionData;
+
+class SWServerRegistration {
+public:
+    explicit SWServerRegistration(SWServer&);
+    SWServerRegistration(const SWServerRegistration&) = delete;
+    ~SWServerRegistration();
+
+    void enqueueJob(const ServiceWorkerJobData&);
+
+private:
+    void jobTimerFired();
+    void performCurrentJob();
+    void rejectCurrentJob(const ExceptionData&);
+
+    void startNextJob();
+    void finishCurrentJob();
+
+    Deque<ServiceWorkerJobData> m_jobQueue;
+    std::unique_ptr<ServiceWorkerJobData> m_currentJob;
+
+    Timer m_jobTimer;
+    SWServer& m_server;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
index 938f288..b7700f4 100644 (file)
@@ -1,3 +1,18 @@
+2017-08-25  Brady Eidson  <beidson@apple.com>
+
+        Introduce ServerWorkerRegistration task queues.
+        https://bugs.webkit.org/show_bug.cgi?id=175851
+
+        Reviewed by Andy Estes.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::WebSWServerConnection):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        (WebKit::WebSWServerConnection::identifier const): Deleted.
+
+        * WebProcess/Storage/WebSWClientConnection.h:
+        (WebKit::WebSWClientConnection::identifier const): Deleted.
+
 2017-08-25  Youenn Fablet  <youenn@apple.com>
 
         [Cache API] UIProcess should provide the directory path where to store Cache Storage data
index df47502..1565588 100644 (file)
@@ -45,9 +45,8 @@ using namespace WebCore;
 namespace WebKit {
 
 WebSWServerConnection::WebSWServerConnection(SWServer& server, IPC::Connection& connection, uint64_t connectionIdentifier, const SessionID& sessionID)
-    : SWServer::Connection(server)
+    : SWServer::Connection(server, connectionIdentifier)
     , m_sessionID(sessionID)
-    , m_identifier(connectionIdentifier)
     , m_connection(connection)
 {
 }
index 3645e5f..6789241 100644 (file)
@@ -44,8 +44,6 @@ public:
     WebSWServerConnection(const WebSWServerConnection&) = delete;
     ~WebSWServerConnection() final;
 
-    uint64_t identifier() const { return m_identifier; }
-
     void disconnectedFromWebProcess();
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
@@ -54,10 +52,9 @@ private:
     void rejectJobInClient(uint64_t jobIdentifier, const WebCore::ExceptionData&) final;
 
     IPC::Connection* messageSenderConnection() final { return m_connection.ptr(); }
-    uint64_t messageSenderDestinationID() final { return m_identifier; }
+    uint64_t messageSenderDestinationID() final { return identifier(); }
 
     PAL::SessionID m_sessionID;
-    uint64_t m_identifier;
 
     Ref<IPC::Connection> m_connection;
 }; // class WebSWServerConnection
index ea9b6f2..51de4bb 100644 (file)
@@ -45,7 +45,7 @@ public:
     WebSWClientConnection(const WebSWClientConnection&) = delete;
     ~WebSWClientConnection() final;
 
-    uint64_t identifier() const { return m_identifier; }
+    uint64_t identifier() const final { return m_identifier; }
 
     void scheduleJobInServer(const WebCore::ServiceWorkerJobData&) final;