Add a SW context process (where SW scripts will actually execute).
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Oct 2017 17:27:08 +0000 (17:27 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Oct 2017 17:27:08 +0000 (17:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178156
Source/WebCore:

Reviewed by Andy Estes.

No new tests (Covered by changes to existing tests).

This patch adds an auxiliary "ServiceWorker context" WebProcess to a WebProcessPool.

This process is where ServiceWorker scripts will execute, separate from the client WebProcess
hosting the page(s) they are serving.

This patch also adds all of the plumbing to pass along a fetched service worker script to this
context WebProcess, as well as message back failure to actually start the script so we can test.

Touches lots of code sites but is basically just a lot of plumbing.

* WebCore.xcodeproj/project.pbxproj:

* workers/service/ServiceWorkerContextData.h: Copied from Source/WebCore/workers/service/server/SWServerWorker.h.
(WebCore::ServiceWorkerContextData::encode const):
(WebCore::ServiceWorkerContextData::decode):

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::finishFetchingScriptInServer):
(WebCore::SWServer::Connection::scriptContextFailedToStart):
(WebCore::SWServer::scriptFetchFinished):
(WebCore::SWServer::scriptContextFailedToStart):
(WebCore::SWServer::createWorker):
* workers/service/server/SWServer.h:

* workers/service/server/SWServerRegistration.cpp:
(WebCore::SWServerRegistration::scriptFetchFinished):
(WebCore::SWServerRegistration::scriptContextFailedToStart):
* workers/service/server/SWServerRegistration.h:

* workers/service/server/SWServerWorker.cpp:
(WebCore::SWServerWorker::SWServerWorker):
(WebCore::SWServerWorker::~SWServerWorker):
* workers/service/server/SWServerWorker.h:
(WebCore::SWServerWorker::create):
(WebCore::SWServerWorker::scriptURL const):
(WebCore::SWServerWorker::script const):
(WebCore::SWServerWorker::type const):
(WebCore::SWServerWorker::workerID const):

Source/WebKit:

Reviewed by Andy Estes.

This patch adds an auxiliary "ServiceWorker context" WebProcess to a WebProcessPool.

This process is where ServiceWorker scripts will execute, separate from the client WebProcess
hosting the page(s) they are serving.

This patch also adds all of the plumbing to pass along a fetched service worker script to this
context WebProcess, as well as message back failure to actually start the script so we can test.

Touches lots of code sites but is basically just a lot of plumbing.

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::WebSWServerConnection):
(WebKit::WebSWServerConnection::startServiceWorkerContext):
(WebKit::WebSWServerConnection::sendToContextProcess):
(WebKit::WebSWServerConnection::setContextConnection):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:

* StorageProcess/StorageProcess.cpp:
(WebKit::StorageProcess::workerContextProcessConnection):
(WebKit::StorageProcess::createWorkerContextProcessConnection):
(WebKit::StorageProcess::didGetWorkerContextProcessConnection):
(WebKit::StorageProcess::serviceWorkerContextFailedToStart):
(WebKit::StorageProcess::registerSWServerConnection):
(WebKit::StorageProcess::unregisterSWServerConnection):
* StorageProcess/StorageProcess.h:
* StorageProcess/StorageProcess.messages.in:

* StorageProcess/StorageToWebProcessConnection.cpp:
(WebKit::StorageToWebProcessConnection::~StorageToWebProcessConnection):
(WebKit::StorageToWebProcessConnection::establishSWServerConnection):
(WebKit::StorageToWebProcessConnection::removeSWServerConnection):
(WebKit::StorageToWebProcessConnection::workerContextProcessConnectionCreated):
* StorageProcess/StorageToWebProcessConnection.h:

* UIProcess/Storage/StorageProcessProxy.cpp:
(WebKit::StorageProcessProxy::create):
(WebKit::StorageProcessProxy::StorageProcessProxy):
(WebKit::StorageProcessProxy::didClose):
(WebKit::StorageProcessProxy::getWorkerContextProcessConnection):
(WebKit::StorageProcessProxy::didGetWorkerContextProcessConnection):
* UIProcess/Storage/StorageProcessProxy.h:
* UIProcess/Storage/StorageProcessProxy.messages.in:

* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::ensureStorageProcessAndWebsiteDataStore):
(WebKit::WebProcessPool::getWorkerContextProcessConnection):
(WebKit::WebProcessPool::didGetWorkerContextProcessConnection):
(WebKit::WebProcessPool::disconnectProcess):
(WebKit::WebProcessPool::createWebPage):
* UIProcess/WebProcessPool.h:

* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::didGetWorkerContextConnection):
* UIProcess/WebProcessProxy.h:
* UIProcess/WebProcessProxy.messages.in:

* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::getWorkerContextConnection):
(WebKit::WebProcess::startServiceWorkerContext):
* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in:

LayoutTests:

Reviewed by Andy Estes.

* http/tests/workers/service/basic-register-exceptions-expected.txt:
* http/tests/workers/service/basic-register-expected.txt:
* http/tests/workers/service/registration-task-queue-scheduling-1-expected.txt:

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

32 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/basic-register-exceptions-expected.txt
LayoutTests/http/tests/workers/service/basic-register-expected.txt
LayoutTests/http/tests/workers/service/registration-task-queue-scheduling-1-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/workers/service/ServiceWorkerContextData.h [new file with mode: 0644]
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerRegistration.cpp
Source/WebCore/workers/service/server/SWServerRegistration.h
Source/WebCore/workers/service/server/SWServerWorker.cpp
Source/WebCore/workers/service/server/SWServerWorker.h
Source/WebKit/ChangeLog
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/StorageProcess/StorageProcess.cpp
Source/WebKit/StorageProcess/StorageProcess.h
Source/WebKit/StorageProcess/StorageProcess.messages.in
Source/WebKit/StorageProcess/StorageToWebProcessConnection.cpp
Source/WebKit/StorageProcess/StorageToWebProcessConnection.h
Source/WebKit/UIProcess/Storage/StorageProcessProxy.cpp
Source/WebKit/UIProcess/Storage/StorageProcessProxy.h
Source/WebKit/UIProcess/Storage/StorageProcessProxy.messages.in
Source/WebKit/UIProcess/WebProcessPool.cpp
Source/WebKit/UIProcess/WebProcessPool.h
Source/WebKit/UIProcess/WebProcessProxy.cpp
Source/WebKit/UIProcess/WebProcessProxy.h
Source/WebKit/UIProcess/WebProcessProxy.messages.in
Source/WebKit/WebProcess/WebProcess.cpp
Source/WebKit/WebProcess/WebProcess.h
Source/WebKit/WebProcess/WebProcess.messages.in

index d7ad780..b7f7974 100644 (file)
@@ -1,3 +1,14 @@
+2017-10-11  Brady Eidson  <beidson@apple.com>
+
+        Add a SW context process (where SW scripts will actually execute).
+        https://bugs.webkit.org/show_bug.cgi?id=178156
+
+        Reviewed by Andy Estes.
+
+        * http/tests/workers/service/basic-register-exceptions-expected.txt:
+        * http/tests/workers/service/basic-register-expected.txt:
+        * http/tests/workers/service/registration-task-queue-scheduling-1-expected.txt:
+
 2017-10-11  Joanmarie Diggs  <jdiggs@igalia.com>
 
         [ATK] Expose value of aria-keyshortcuts as object attribute
index 34f6496..87c5fb2 100644 (file)
@@ -4,7 +4,7 @@ CONSOLE MESSAGE: line 40: Registration failed with error: TypeError: serviceWork
 CONSOLE MESSAGE: line 50: Registration failed with error: TypeError: serviceWorker.register() must be called with a script URL whose path does not contain '%2f' or '%5c'
 CONSOLE MESSAGE: line 60: Registration failed with error: TypeError: Scope URL provided to serviceWorker.register() must be either HTTP or HTTPS
 CONSOLE MESSAGE: line 70: Registration failed with error: TypeError: Scope URL provided to serviceWorker.register() cannot have a path that contains '%2f' or '%5c'
-CONSOLE MESSAGE: line 10: Registration failed with error: UnknownError: Script URL http://127.0.0.1:8000/workers/service/image-mime-type.php fetched with 0 characters, but we're not using the result yet
+CONSOLE MESSAGE: line 10: Registration failed with error: UnknownError: Failed to start service worker script of length 0
 CONSOLE MESSAGE: line 80: Registration failed with error: SecurityError: Script origin does not match the registering client's origin
 CONSOLE MESSAGE: line 91: Registration failed with error: SecurityError: Scope origin does not match the registering client's origin
 
index 4940778..5133bb2 100644 (file)
@@ -1,3 +1,3 @@
-CONSOLE MESSAGE: line 10: Registration failed with error: UnknownError: Script URL http://127.0.0.1:8000/workers/service/resources/empty-worker.js fetched with 41 characters, but we're not using the result yet
-CONSOLE MESSAGE: line 21: Registration failed with error: UnknownError: Script URL http://127.0.0.1:8000/workers/service/resources/empty-worker-doesnt-exist.js fetched with 0 characters, but we're not using the result yet
+CONSOLE MESSAGE: line 10: Registration failed with error: UnknownError: Failed to start service worker script of length 41
+CONSOLE MESSAGE: line 21: Registration failed with error: UnknownError: Failed to start service worker script of length 0
 
index c3972cf..0d49e35 100644 (file)
@@ -1,3 +1,51 @@
+2017-10-11  Brady Eidson  <beidson@apple.com>
+
+        Add a SW context process (where SW scripts will actually execute).
+        https://bugs.webkit.org/show_bug.cgi?id=178156
+        
+        Reviewed by Andy Estes.
+
+        No new tests (Covered by changes to existing tests).
+
+        This patch adds an auxiliary "ServiceWorker context" WebProcess to a WebProcessPool.
+
+        This process is where ServiceWorker scripts will execute, separate from the client WebProcess
+        hosting the page(s) they are serving.
+
+        This patch also adds all of the plumbing to pass along a fetched service worker script to this
+        context WebProcess, as well as message back failure to actually start the script so we can test.
+
+        Touches lots of code sites but is basically just a lot of plumbing.
+
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * workers/service/ServiceWorkerContextData.h: Copied from Source/WebCore/workers/service/server/SWServerWorker.h.
+        (WebCore::ServiceWorkerContextData::encode const):
+        (WebCore::ServiceWorkerContextData::decode):
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::Connection::finishFetchingScriptInServer):
+        (WebCore::SWServer::Connection::scriptContextFailedToStart):
+        (WebCore::SWServer::scriptFetchFinished):
+        (WebCore::SWServer::scriptContextFailedToStart):
+        (WebCore::SWServer::createWorker):
+        * workers/service/server/SWServer.h:
+
+        * workers/service/server/SWServerRegistration.cpp:
+        (WebCore::SWServerRegistration::scriptFetchFinished):
+        (WebCore::SWServerRegistration::scriptContextFailedToStart):
+        * workers/service/server/SWServerRegistration.h:
+
+        * workers/service/server/SWServerWorker.cpp:
+        (WebCore::SWServerWorker::SWServerWorker):
+        (WebCore::SWServerWorker::~SWServerWorker):
+        * workers/service/server/SWServerWorker.h:
+        (WebCore::SWServerWorker::create):
+        (WebCore::SWServerWorker::scriptURL const):
+        (WebCore::SWServerWorker::script const):
+        (WebCore::SWServerWorker::type const):
+        (WebCore::SWServerWorker::workerID const):
+
 2017-10-11  Joanmarie Diggs  <jdiggs@igalia.com>
 
         [ATK] Expose value of aria-keyshortcuts as object attribute
index de92a89..99d4182 100644 (file)
                51C61B0B1DE536E7008A212D /* ScrollingMomentumCalculator.h in Headers */ = {isa = PBXBuildFile; fileRef = 51C61B091DE536E7008A212D /* ScrollingMomentumCalculator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51C81B890C4422F70019ECE3 /* FTPDirectoryParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51C81B870C4422F70019ECE3 /* FTPDirectoryParser.cpp */; };
                51C81B8A0C4422F70019ECE3 /* FTPDirectoryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 51C81B880C4422F70019ECE3 /* FTPDirectoryParser.h */; };
+               51CA7EE91F883390003D3131 /* ServiceWorkerContextData.h in Headers */ = {isa = PBXBuildFile; fileRef = 51CA7EE71F8832E0003D3131 /* ServiceWorkerContextData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51CBFC990D10E483002DBF51 /* CachedFramePlatformData.h in Headers */ = {isa = PBXBuildFile; fileRef = 51CBFC980D10E483002DBF51 /* CachedFramePlatformData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                51D1248B1E73627F002B2820 /* NetworkStorageSessionCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51D1248A1E73625C002B2820 /* NetworkStorageSessionCocoa.mm */; };
                51D1248D1E7364AA002B2820 /* CookieCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51D1248C1E736456002B2820 /* CookieCocoa.mm */; };
                51C61B091DE536E7008A212D /* ScrollingMomentumCalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingMomentumCalculator.h; sourceTree = "<group>"; };
                51C81B870C4422F70019ECE3 /* FTPDirectoryParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectoryParser.cpp; sourceTree = "<group>"; };
                51C81B880C4422F70019ECE3 /* FTPDirectoryParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FTPDirectoryParser.h; sourceTree = "<group>"; };
+               51CA7EE71F8832E0003D3131 /* ServiceWorkerContextData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerContextData.h; sourceTree = "<group>"; };
                51CBFC980D10E483002DBF51 /* CachedFramePlatformData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedFramePlatformData.h; sourceTree = "<group>"; };
                51D1248A1E73625C002B2820 /* NetworkStorageSessionCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkStorageSessionCocoa.mm; sourceTree = "<group>"; };
                51D1248C1E736456002B2820 /* CookieCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CookieCocoa.mm; sourceTree = "<group>"; };
                                51F175581F3EBC0C00C74950 /* ServiceWorkerContainer.cpp */,
                                51F175571F3EBC0C00C74950 /* ServiceWorkerContainer.h */,
                                51F175561F3EBC0C00C74950 /* ServiceWorkerContainer.idl */,
+                               51CA7EE71F8832E0003D3131 /* ServiceWorkerContextData.h */,
                                517A535C1F5899F200DCDC0A /* ServiceWorkerFetchResult.h */,
                                51F175551F3EBC0C00C74950 /* ServiceWorkerGlobalScope.cpp */,
                                51F175541F3EBC0C00C74950 /* ServiceWorkerGlobalScope.h */,
                                2D93AEE319DF5641002A86C3 /* ServicesOverlayController.h in Headers */,
                                51F1755D1F3EBC8300C74950 /* ServiceWorker.h in Headers */,
                                51F1755F1F3EBC8300C74950 /* ServiceWorkerContainer.h in Headers */,
+                               51CA7EE91F883390003D3131 /* ServiceWorkerContextData.h in Headers */,
                                517A535D1F5899FE00DCDC0A /* ServiceWorkerFetchResult.h in Headers */,
                                51F175611F3EBC8300C74950 /* ServiceWorkerGlobalScope.h in Headers */,
                                51F175631F3EBC8300C74950 /* ServiceWorkerJob.h in Headers */,
diff --git a/Source/WebCore/workers/service/ServiceWorkerContextData.h b/Source/WebCore/workers/service/ServiceWorkerContextData.h
new file mode 100644 (file)
index 0000000..7c639e7
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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
+
+#include "ServiceWorkerRegistrationKey.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+namespace WebCore {
+
+struct ServiceWorkerContextData {
+    ServiceWorkerRegistrationKey registrationKey;
+    String workerID;
+    String script;
+    
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<ServiceWorkerContextData> decode(Decoder&);
+};
+
+template<class Encoder>
+void ServiceWorkerContextData::encode(Encoder& encoder) const
+{
+    encoder << registrationKey << workerID << script;
+}
+
+template<class Decoder>
+std::optional<ServiceWorkerContextData> ServiceWorkerContextData::decode(Decoder& decoder)
+{
+    auto registrationKey = ServiceWorkerRegistrationKey::decode(decoder);
+    if (!registrationKey)
+        return std::nullopt;
+
+    String workerID;
+    if (!decoder.decode(workerID))
+        return std::nullopt;
+
+    String script;
+    if (!decoder.decode(script))
+        return std::nullopt;
+    
+    return {{ WTFMove(*registrationKey), WTFMove(workerID), WTFMove(script) }};
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
index 6f81ab2..055900c 100644 (file)
 #include "ExceptionData.h"
 #include "Logging.h"
 #include "SWServerRegistration.h"
+#include "SWServerWorker.h"
+#include "ServiceWorkerContextData.h"
 #include "ServiceWorkerFetchResult.h"
 #include "ServiceWorkerJobData.h"
+#include <wtf/UUID.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -75,7 +78,12 @@ void SWServer::Connection::scheduleJobInServer(const ServiceWorkerJobData& jobDa
 
 void SWServer::Connection::finishFetchingScriptInServer(const ServiceWorkerFetchResult& result)
 {
-    m_server.scriptFetchFinished(result);
+    m_server.scriptFetchFinished(*this, result);
+}
+
+void SWServer::Connection::scriptContextFailedToStart(const ServiceWorkerRegistrationKey& registrationKey, const String& workerID, const String& message)
+{
+    m_server.scriptContextFailedToStart(*this, registrationKey, workerID, message);
 }
 
 SWServer::SWServer()
@@ -128,7 +136,7 @@ void SWServer::startScriptFetch(const ServiceWorkerJobData& jobData)
     connection->startScriptFetchInClient(jobData.identifier());
 }
 
-void SWServer::scriptFetchFinished(const ServiceWorkerFetchResult& result)
+void SWServer::scriptFetchFinished(Connection& connection, const ServiceWorkerFetchResult& result)
 {
     LOG(ServiceWorker, "Server handling scriptFetchFinished for current job %" PRIu64 "-%" PRIu64 " in client", result.connectionIdentifier, result.jobIdentifier);
 
@@ -138,7 +146,27 @@ void SWServer::scriptFetchFinished(const ServiceWorkerFetchResult& result)
     if (!registration)
         return;
 
-    registration->scriptFetchFinished(result);
+    registration->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);
+}
+
+Ref<SWServerWorker> SWServer::createWorker(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey, const URL& url, const String& script, WorkerType type)
+{
+    String workerID = createCanonicalUUIDString();
+    
+    auto result = m_workersByID.add(workerID, SWServerWorker::create(registrationKey, url, script, type, workerID));
+    ASSERT(result.isNewEntry);
+    
+    connection.startServiceWorkerContext({ registrationKey, workerID, script });
+    
+    return result.iterator->value.get();
 }
 
 void SWServer::taskThreadEntryPoint()
index a1fc5d3..3aafb80 100644 (file)
@@ -27,7 +27,6 @@
 
 #if ENABLE(SERVICE_WORKER)
 
-#include "SWServerRegistration.h"
 #include "ServiceWorkerJob.h"
 #include "ServiceWorkerRegistrationKey.h"
 #include <wtf/CrossThreadQueue.h>
@@ -42,7 +41,9 @@
 namespace WebCore {
 
 class SWServerRegistration;
+class SWServerWorker;
 struct ExceptionData;
+struct ServiceWorkerContextData;
 struct ServiceWorkerFetchResult;
 struct ServiceWorkerRegistrationData;
 
@@ -53,6 +54,8 @@ public:
     public:
         WEBCORE_EXPORT virtual ~Connection();
 
+        WEBCORE_EXPORT void scriptContextFailedToStart(const ServiceWorkerRegistrationKey&, const String& workerID, const String& message);
+
     protected:
         WEBCORE_EXPORT Connection(SWServer&, uint64_t identifier);
         SWServer& server() { return m_server; }
@@ -61,10 +64,14 @@ public:
         WEBCORE_EXPORT void finishFetchingScriptInServer(const ServiceWorkerFetchResult&);
 
     private:
+        // Messages to the client WebProcess
         virtual void rejectJobInClient(uint64_t jobIdentifier, const ExceptionData&) = 0;
         virtual void resolveJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationData&) = 0;
         virtual void startScriptFetchInClient(uint64_t jobIdentifier) = 0;
 
+        // Messages to the SW host WebProcess
+        virtual void startServiceWorkerContext(const ServiceWorkerContextData&) = 0;
+
         SWServer& m_server;
     };
 
@@ -79,6 +86,8 @@ public:
     void postTask(CrossThreadTask&&);
     void postTaskReply(CrossThreadTask&&);
 
+    Ref<SWServerWorker> createWorker(Connection&, const ServiceWorkerRegistrationKey&, const URL&, const String& script, WorkerType);
+    
 private:
     void registerConnection(Connection&);
     void unregisterConnection(Connection&);
@@ -86,11 +95,14 @@ private:
     void taskThreadEntryPoint();
     void handleTaskRepliesOnMainThread();
 
-    void scriptFetchFinished(const ServiceWorkerFetchResult&);
+    void scriptFetchFinished(Connection&, const ServiceWorkerFetchResult&);
+    void scriptContextFailedToStart(Connection&, const ServiceWorkerRegistrationKey&, const String& workerID, const String& message);
 
     HashMap<uint64_t, Connection*> m_connections;
     HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations;
 
+    HashMap<String, Ref<SWServerWorker>> m_workersByID;
+
     RefPtr<Thread> m_taskThread;
     Lock m_taskThreadLock;
 
index d511ddd..d17a476 100644 (file)
@@ -64,18 +64,32 @@ void SWServerRegistration::enqueueJob(const ServiceWorkerJobData& jobData)
         m_jobTimer.startOneShot(0_s);
 }
 
-void SWServerRegistration::scriptFetchFinished(const ServiceWorkerFetchResult& result)
+void SWServerRegistration::scriptFetchFinished(SWServer::Connection& connection, const ServiceWorkerFetchResult& result)
 {
     ASSERT(m_currentJob && m_currentJob->identifier() == result.jobIdentifier);
 
-    // FIXME: We fetched the script contents but don't do anything with them yet.
-    // These errors are for testing the current state of the feature.
+    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.
 
-    String message;
-    if (result.scriptError.isNull())
-        message = makeString("Script URL ", m_currentJob->scriptURL.string(), " fetched with ", String::number(result.script.length()), " characters, but we're not using the result yet");
-    else
-        message = makeString("Script URL ", m_currentJob->scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription());
+        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.createWorker(connection, m_registrationKey, m_currentJob->scriptURL, result.script, WorkerType::Classic);
+}
+
+void SWServerRegistration::scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message)
+{
+    ASSERT(m_currentJob);
+    UNUSED_PARAM(workerID);
 
     rejectCurrentJob(ExceptionData { UnknownError, message });
 }
index f768546..7ccf121 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "SWServer.h"
 #include "ServiceWorkerJobData.h"
 #include "ServiceWorkerRegistrationData.h"
 #include "Timer.h"
@@ -47,8 +48,9 @@ public:
     ~SWServerRegistration();
 
     void enqueueJob(const ServiceWorkerJobData&);
-    void scriptFetchFinished(const ServiceWorkerFetchResult&);
-
+    void scriptFetchFinished(SWServer::Connection&, const ServiceWorkerFetchResult&);
+    void scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message);
+    
     ServiceWorkerRegistrationData data() const;
 
 private:
@@ -77,6 +79,8 @@ private:
     std::unique_ptr<SWServerWorker> m_activeWorker;
     URL m_scopeURL;
     std::optional<ServiceWorkerUpdateViaCache> m_updateViaCache;
+    
+    double m_lastUpdateTime { 0 };
 
     Timer m_jobTimer;
     SWServer& m_server;
index 4a7fdcd..2a66f3e 100644 (file)
 
 #if ENABLE(SERVICE_WORKER)
 
-#include <wtf/MainThread.h>
-
 namespace WebCore {
 
-SWServerWorker::SWServerWorker(const URL& url)
-    : m_scriptURL(url)
+SWServerWorker::SWServerWorker(const ServiceWorkerRegistrationKey& registrationKey, const URL& url, const String& script, WorkerType type, const String& workerID)
+    : m_registrationKey(registrationKey)
+    , m_scriptURL(url)
+    , m_script(script)
+    , m_workerID(workerID)
+    , m_type(type)
 {
-    ASSERT(!isMainThread());
 }
 
 SWServerWorker::~SWServerWorker()
 {
-    ASSERT(!isMainThread());
 }
 
 } // namespace WebCore
index 12dc357..13e3a29 100644 (file)
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "ServiceWorkerRegistrationKey.h"
 #include "URL.h"
+#include <wtf/ThreadSafeRefCounted.h>
 
 namespace WebCore {
 
-class SWServerWorker {
+enum class WorkerType;
+
+class SWServerWorker : public ThreadSafeRefCounted<SWServerWorker> {
 public:
-    SWServerWorker(const URL&);
+    static Ref<SWServerWorker> create(const ServiceWorkerRegistrationKey& registrationKey, const URL& url, const String& script, WorkerType type, const String& workerID)
+    {
+        return adoptRef(*new SWServerWorker(registrationKey, url, script, type, workerID));
+    }
+    
     SWServerWorker(const SWServerWorker&) = delete;
     ~SWServerWorker();
-    const URL& scriptURL() const { return m_scriptURL; }
 
+    const URL& scriptURL() const { return m_scriptURL; }
+    const String& script() const { return m_script; }
+    WorkerType type() const { return m_type; }
+    const String& workerID() const { return m_workerID; }
+    
 private:
+    SWServerWorker(const ServiceWorkerRegistrationKey&, const URL&, const String& script, WorkerType, const String& workerID);
+
+    ServiceWorkerRegistrationKey m_registrationKey;
     URL m_scriptURL;
+    String m_script;
+    String m_workerID;
+    WorkerType m_type;
 };
 
 } // namespace WebCore
index 3edbfa1..4557a44 100644 (file)
@@ -1,3 +1,72 @@
+2017-10-11  Brady Eidson  <beidson@apple.com>
+
+        Add a SW context process (where SW scripts will actually execute).
+        https://bugs.webkit.org/show_bug.cgi?id=178156
+
+        Reviewed by Andy Estes.
+
+        This patch adds an auxiliary "ServiceWorker context" WebProcess to a WebProcessPool.
+
+        This process is where ServiceWorker scripts will execute, separate from the client WebProcess
+        hosting the page(s) they are serving.
+
+        This patch also adds all of the plumbing to pass along a fetched service worker script to this
+        context WebProcess, as well as message back failure to actually start the script so we can test.
+
+        Touches lots of code sites but is basically just a lot of plumbing.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::WebSWServerConnection):
+        (WebKit::WebSWServerConnection::startServiceWorkerContext):
+        (WebKit::WebSWServerConnection::sendToContextProcess):
+        (WebKit::WebSWServerConnection::setContextConnection):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+
+        * StorageProcess/StorageProcess.cpp:
+        (WebKit::StorageProcess::workerContextProcessConnection):
+        (WebKit::StorageProcess::createWorkerContextProcessConnection):
+        (WebKit::StorageProcess::didGetWorkerContextProcessConnection):
+        (WebKit::StorageProcess::serviceWorkerContextFailedToStart):
+        (WebKit::StorageProcess::registerSWServerConnection):
+        (WebKit::StorageProcess::unregisterSWServerConnection):
+        * StorageProcess/StorageProcess.h:
+        * StorageProcess/StorageProcess.messages.in:
+
+        * StorageProcess/StorageToWebProcessConnection.cpp:
+        (WebKit::StorageToWebProcessConnection::~StorageToWebProcessConnection):
+        (WebKit::StorageToWebProcessConnection::establishSWServerConnection):
+        (WebKit::StorageToWebProcessConnection::removeSWServerConnection):
+        (WebKit::StorageToWebProcessConnection::workerContextProcessConnectionCreated):
+        * StorageProcess/StorageToWebProcessConnection.h:
+
+        * UIProcess/Storage/StorageProcessProxy.cpp:
+        (WebKit::StorageProcessProxy::create):
+        (WebKit::StorageProcessProxy::StorageProcessProxy):
+        (WebKit::StorageProcessProxy::didClose):
+        (WebKit::StorageProcessProxy::getWorkerContextProcessConnection):
+        (WebKit::StorageProcessProxy::didGetWorkerContextProcessConnection):
+        * UIProcess/Storage/StorageProcessProxy.h:
+        * UIProcess/Storage/StorageProcessProxy.messages.in:
+
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::ensureStorageProcessAndWebsiteDataStore):
+        (WebKit::WebProcessPool::getWorkerContextProcessConnection):
+        (WebKit::WebProcessPool::didGetWorkerContextProcessConnection):
+        (WebKit::WebProcessPool::disconnectProcess):
+        (WebKit::WebProcessPool::createWebPage):
+        * UIProcess/WebProcessPool.h:
+
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::didGetWorkerContextConnection):
+        * UIProcess/WebProcessProxy.h:
+        * UIProcess/WebProcessProxy.messages.in:
+
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::getWorkerContextConnection):
+        (WebKit::WebProcess::startServiceWorkerContext):
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in:
+
 2017-10-11  Don Olmstead  <don.olmstead@sony.com>
 
         Remove ENABLE_NETWORK_CACHE
index d8e6c24..5498963 100644 (file)
 #include "Logging.h"
 #include "StorageToWebProcessConnectionMessages.h"
 #include "WebProcess.h"
+#include "WebProcessMessages.h"
 #include "WebSWClientConnectionMessages.h"
 #include "WebSWServerConnectionMessages.h"
 #include "WebToStorageProcessConnection.h"
 #include <WebCore/ExceptionData.h>
 #include <WebCore/NotImplemented.h>
+#include <WebCore/ServiceWorkerContextData.h>
 #include <WebCore/ServiceWorkerJobData.h>
+#include <WebCore/ServiceWorkerRegistrationData.h>
 #include <wtf/MainThread.h>
 
 using namespace PAL;
@@ -48,7 +51,7 @@ namespace WebKit {
 WebSWServerConnection::WebSWServerConnection(SWServer& server, IPC::Connection& connection, uint64_t connectionIdentifier, const SessionID& sessionID)
     : SWServer::Connection(server, connectionIdentifier)
     , m_sessionID(sessionID)
-    , m_connection(connection)
+    , m_contentConnection(connection)
 {
 }
 
@@ -76,6 +79,33 @@ void WebSWServerConnection::startScriptFetchInClient(uint64_t jobIdentifier)
     send(Messages::WebSWClientConnection::StartScriptFetchForServer(jobIdentifier));
 }
 
+void WebSWServerConnection::startServiceWorkerContext(const ServiceWorkerContextData& data)
+{
+    if (sendToContextProcess(Messages::WebProcess::StartServiceWorkerContext(identifier(), data)))
+        return;
+
+    m_pendingContextDatas.append(data);
+}
+
+template<typename U> bool WebSWServerConnection::sendToContextProcess(U&& message)
+{
+    if (!m_contextConnection)
+        return false;
+
+    return m_contextConnection->send<U>(WTFMove(message), 0);
+}
+
+void WebSWServerConnection::setContextConnection(IPC::Connection* connection)
+{
+    m_contextConnection = connection;
+
+    // We can now start any pending service worker contexts.
+    for (auto& pendingContextData : m_pendingContextDatas)
+        startServiceWorkerContext(pendingContextData);
+    
+    m_pendingContextDatas.clear();
+}
+    
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)
index b3ce76c..b2be040 100644 (file)
@@ -34,6 +34,7 @@
 
 namespace WebCore {
 struct ExceptionData;
+struct ServiceWorkerRegistrationKey;
 }
 
 namespace WebKit {
@@ -45,20 +46,29 @@ public:
     ~WebSWServerConnection() final;
 
     void disconnectedFromWebProcess();
+    void setContextConnection(IPC::Connection*);
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
 private:
-    // Implement SWServer::Connection
+    // Implement SWServer::Connection (Messages to the client WebProcess)
     void rejectJobInClient(uint64_t jobIdentifier, const WebCore::ExceptionData&) final;
     void resolveJobInClient(uint64_t jobIdentifier, const WebCore::ServiceWorkerRegistrationData&) final;
     void startScriptFetchInClient(uint64_t jobIdentifier) final;
 
-    IPC::Connection* messageSenderConnection() final { return m_connection.ptr(); }
+    // Messages to the SW context WebProcess
+    void startServiceWorkerContext(const WebCore::ServiceWorkerContextData&) final;
+    
+    IPC::Connection* messageSenderConnection() final { return m_contentConnection.ptr(); }
     uint64_t messageSenderDestinationID() final { return identifier(); }
 
+    template<typename U> bool sendToContextProcess(U&& message);
+    
     PAL::SessionID m_sessionID;
 
-    Ref<IPC::Connection> m_connection;
+    Ref<IPC::Connection> m_contentConnection;
+    RefPtr<IPC::Connection> m_contextConnection;
+    
+    Deque<WebCore::ServiceWorkerContextData> m_pendingContextDatas;
 }; // class WebSWServerConnection
 
 } // namespace WebKit
index 3b363ec..e10809c 100644 (file)
@@ -31,6 +31,7 @@
 #include "StorageProcessProxyMessages.h"
 #include "StorageToWebProcessConnection.h"
 #include "WebCoreArgumentCoders.h"
+#include "WebSWServerConnection.h"
 #include "WebsiteData.h"
 #include <WebCore/FileSystem.h>
 #include <WebCore/IDBKeyData.h>
@@ -329,6 +330,63 @@ SWServer& StorageProcess::swServerForSession(PAL::SessionID sessionID)
     ASSERT(result.iterator->value);
     return *result.iterator->value;
 }
+
+IPC::Connection* StorageProcess::workerContextProcessConnection()
+{
+    return m_workerContextProcessConnection.get();
+}
+
+void StorageProcess::createWorkerContextProcessConnection()
+{
+    if (m_waitingForWorkerContextProcessConnection)
+        return;
+    
+    m_waitingForWorkerContextProcessConnection = true;
+    parentProcessConnection()->send(Messages::StorageProcessProxy::GetWorkerContextProcessConnection(), 0);
+}
+
+void StorageProcess::didGetWorkerContextProcessConnection(const IPC::Attachment& encodedConnectionIdentifier)
+{
+    ASSERT(m_waitingForWorkerContextProcessConnection);
+    m_waitingForWorkerContextProcessConnection = false;
+
+#if USE(UNIX_DOMAIN_SOCKETS)
+    IPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.releaseFileDescriptor();
+#elif OS(DARWIN)
+    IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port());
+#else
+    ASSERT_NOT_REACHED();
+#endif
+
+    if (IPC::Connection::identifierIsNull(connectionIdentifier)) {
+        LOG_ERROR("StorageProcess::didGetWorkerContextProcessConnection - Received null connection identifier");
+        return;
+    }
+
+    m_workerContextProcessConnection = IPC::Connection::createClientConnection(connectionIdentifier, *this);
+    m_workerContextProcessConnection->open();
+    
+    for (auto& connection : m_storageToWebProcessConnections)
+        connection->workerContextProcessConnectionCreated();
+}
+
+void StorageProcess::serviceWorkerContextFailedToStart(uint64_t serverConnectionIdentifier, const ServiceWorkerRegistrationKey& registrationKey, const String& workerID, const String& message)
+{
+    if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
+        connection->scriptContextFailedToStart(registrationKey, workerID, message);
+}
+
+void StorageProcess::registerSWServerConnection(WebSWServerConnection& connection)
+{
+    ASSERT(!m_swServerConnections.contains(connection.identifier()));
+    m_swServerConnections.add(connection.identifier(), &connection);
+}
+
+void StorageProcess::unregisterSWServerConnection(WebSWServerConnection& connection)
+{
+    ASSERT(m_swServerConnections.get(connection.identifier()) == &connection);
+    m_swServerConnections.remove(connection.identifier());
+}
 #endif
 
 #if !PLATFORM(COCOA)
index f408334..ca41553 100644 (file)
 namespace WebCore {
 class SWServer;
 struct SecurityOriginData;
+struct ServiceWorkerRegistrationKey;
 }
 
 namespace WebKit {
 
 class StorageToWebProcessConnection;
+class WebSWServerConnection;
 enum class WebsiteDataType;
 struct StorageProcessCreationParameters;
 
@@ -67,12 +69,19 @@ public:
     void accessToTemporaryFileComplete(const String& path) final;
 #endif
 
+#if ENABLE(SERVICE_WORKER)
+    IPC::Connection* workerContextProcessConnection();
+    void createWorkerContextProcessConnection();
+#endif
+
 #if ENABLE(SANDBOX_EXTENSIONS)
     void getSandboxExtensionsForBlobFiles(const Vector<String>& filenames, WTF::Function<void (SandboxExtension::HandleArray&&)>&& completionHandler);
 #endif
 
 #if ENABLE(SERVICE_WORKER)
     WebCore::SWServer& swServerForSession(PAL::SessionID);
+    void registerSWServerConnection(WebSWServerConnection&);
+    void unregisterSWServerConnection(WebSWServerConnection&);
 #endif
 
 private:
@@ -101,7 +110,10 @@ private:
     void grantSandboxExtensionsForBlobs(const Vector<String>& paths, const SandboxExtension::HandleArray&);
     void didGetSandboxExtensionsForBlobFiles(uint64_t requestID, SandboxExtension::HandleArray&&);
 #endif
-
+#if ENABLE(SERVICE_WORKER)
+    void didGetWorkerContextProcessConnection(const IPC::Attachment& encodedConnectionIdentifier);
+    void serviceWorkerContextFailedToStart(uint64_t serverConnectionIdentifier, const WebCore::ServiceWorkerRegistrationKey&, const String& workerID, const String& message);
+#endif
 #if ENABLE(INDEXED_DATABASE)
     Vector<WebCore::SecurityOriginData> indexedDatabaseOrigins(const String& path);
 #endif
@@ -125,7 +137,12 @@ private:
     Lock m_storageTaskMutex;
     
 #if ENABLE(SERVICE_WORKER)
+    void didCreateWorkerContextProcessConnection(const IPC::Attachment&);
+
+    RefPtr<IPC::Connection> m_workerContextProcessConnection;
+    bool m_waitingForWorkerContextProcessConnection { false };
     HashMap<PAL::SessionID, std::unique_ptr<WebCore::SWServer>> m_swServers;
+    HashMap<uint64_t, WebSWServerConnection*> m_swServerConnections;
 #endif
 };
 
index c9deadf..1802f0d 100644 (file)
@@ -34,4 +34,9 @@ messages -> StorageProcess LegacyReceiver {
     GrantSandboxExtensionsForBlobs(Vector<String> paths, WebKit::SandboxExtension::HandleArray extensions)
     DidGetSandboxExtensionsForBlobFiles(uint64_t requestID, WebKit::SandboxExtension::HandleArray extensions)
 #endif
+
+#if ENABLE(SERVICE_WORKER)
+    DidGetWorkerContextProcessConnection(IPC::Attachment connectionHandle)
+    ServiceWorkerContextFailedToStart(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerRegistrationKey registrationKey, String workerID, String message)
+#endif
 }
index 27bad1c..4545bc4 100644 (file)
@@ -55,6 +55,11 @@ StorageToWebProcessConnection::StorageToWebProcessConnection(IPC::Connection::Id
 StorageToWebProcessConnection::~StorageToWebProcessConnection()
 {
     m_connection->invalidate();
+
+#if ENABLE(SERVICE_WORKER)
+    for (auto& connection : m_swConnections.values())
+        StorageProcess::singleton().unregisterSWServerConnection(*connection);
+#endif
 }
 
 void StorageToWebProcessConnection::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
@@ -138,7 +143,15 @@ void StorageToWebProcessConnection::establishSWServerConnection(SessionID sessio
     ASSERT(!m_swConnections.contains(serverConnectionIdentifier));
 
     auto& server = StorageProcess::singleton().swServerForSession(sessionID);
-    m_swConnections.set(serverConnectionIdentifier, std::make_unique<WebSWServerConnection>(server, m_connection.get(), serverConnectionIdentifier, sessionID));
+    auto connectionResult = m_swConnections.add(serverConnectionIdentifier, std::make_unique<WebSWServerConnection>(server, m_connection.get(), serverConnectionIdentifier, sessionID));
+    ASSERT(connectionResult.isNewEntry);
+
+    StorageProcess::singleton().registerSWServerConnection(*(connectionResult.iterator->value));
+
+    if (auto* connection = StorageProcess::singleton().workerContextProcessConnection())
+        connectionResult.iterator->value->setContextConnection(connection);
+    else
+        StorageProcess::singleton().createWorkerContextProcessConnection();
 }
 
 void StorageToWebProcessConnection::removeSWServerConnection(uint64_t serverConnectionIdentifier)
@@ -146,8 +159,18 @@ void StorageToWebProcessConnection::removeSWServerConnection(uint64_t serverConn
     ASSERT(m_swConnections.contains(serverConnectionIdentifier));
 
     auto connection = m_swConnections.take(serverConnectionIdentifier);
+    StorageProcess::singleton().unregisterSWServerConnection(*connection);
     connection->disconnectedFromWebProcess();
 }
+
+void StorageToWebProcessConnection::workerContextProcessConnectionCreated()
+{
+    auto* ipcConnection = StorageProcess::singleton().workerContextProcessConnection();
+    ASSERT(ipcConnection);
+
+    for (auto& swConnection : m_swConnections.values())
+        swConnection->setContextConnection(ipcConnection);
+}
 #endif
 
 #if ENABLE(INDEXED_DATABASE)
@@ -169,5 +192,4 @@ void StorageToWebProcessConnection::removeIDBConnectionToServer(uint64_t serverC
 }
 #endif
 
-
 } // namespace WebKit
index ed65802..5b9ce8a 100644 (file)
@@ -44,6 +44,10 @@ public:
 
     IPC::Connection& connection() { return m_connection.get(); }
 
+#if ENABLE(SERVICE_WORKER)
+    void workerContextProcessConnectionCreated();
+#endif
+
 private:
     StorageToWebProcessConnection(IPC::Connection::Identifier);
 
index 55cfff5..742da5a 100644 (file)
@@ -44,13 +44,13 @@ static uint64_t generateCallbackID()
     return ++callbackID;
 }
 
-Ref<StorageProcessProxy> StorageProcessProxy::create(WebProcessPool* processPool)
+Ref<StorageProcessProxy> StorageProcessProxy::create(WebProcessPool& processPool)
 {
     return adoptRef(*new StorageProcessProxy(processPool));
 }
 
-StorageProcessProxy::StorageProcessProxy(WebProcessPool* processPool)
-    : ChildProcessProxy(processPool->alwaysRunsAtBackgroundPriority())
+StorageProcessProxy::StorageProcessProxy(WebProcessPool& processPool)
+    : ChildProcessProxy(processPool.alwaysRunsAtBackgroundPriority())
     , m_processPool(processPool)
     , m_numPendingConnectionRequests(0)
 {
@@ -151,7 +151,7 @@ void StorageProcessProxy::didClose(IPC::Connection&)
     m_pendingDeleteWebsiteDataForOriginsCallbacks.clear();
 
     // Tell ProcessPool to forget about this storage process. This may cause us to be deleted.
-    m_processPool->storageProcessCrashed(this);
+    m_processPool.storageProcessCrashed(this);
 }
 
 void StorageProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName)
@@ -220,4 +220,20 @@ void StorageProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Con
     m_numPendingConnectionRequests = 0;
 }
 
+#if ENABLE(SERVICE_WORKER)
+void StorageProcessProxy::getWorkerContextProcessConnection()
+{
+    ASSERT(!m_waitingOnWorkerContextProcessConnection);
+    m_waitingOnWorkerContextProcessConnection = true;
+    
+    m_processPool.getWorkerContextProcessConnection(*this);
+}
+
+void StorageProcessProxy::didGetWorkerContextProcessConnection(const IPC::Attachment& connection)
+{
+    send(Messages::StorageProcess::DidGetWorkerContextProcessConnection(connection), 0);
+}
+
+#endif
+
 } // namespace WebKit
index c2d2eba..fc91719 100644 (file)
@@ -48,7 +48,7 @@ struct WebsiteData;
 
 class StorageProcessProxy : public ChildProcessProxy {
 public:
-    static Ref<StorageProcessProxy> create(WebProcessPool*);
+    static Ref<StorageProcessProxy> create(WebProcessPool&);
     ~StorageProcessProxy();
 
     void fetchWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, WTF::Function<void(WebsiteData)>&& completionHandler);
@@ -57,8 +57,12 @@ public:
 
     void getStorageProcessConnection(Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&&);
 
+#if ENABLE(SERVICE_WORKER)
+    void didGetWorkerContextProcessConnection(const IPC::Attachment& connection);
+#endif
+
 private:
-    StorageProcessProxy(WebProcessPool*);
+    StorageProcessProxy(WebProcessPool&);
 
     // ChildProcessProxy
     void getLaunchOptions(ProcessLauncher::LaunchOptions&) override;
@@ -79,11 +83,15 @@ private:
 #if ENABLE(SANDBOX_EXTENSIONS)
     void getSandboxExtensionsForBlobFiles(uint64_t requestID, const Vector<String>& paths);
 #endif
+#if ENABLE(SERVICE_WORKER)
+    void getWorkerContextProcessConnection();
+    bool m_waitingOnWorkerContextProcessConnection { false };
+#endif
 
     // ProcessLauncher::Client
     void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
 
-    WebProcessPool* m_processPool;
+    WebProcessPool& m_processPool;
 
     unsigned m_numPendingConnectionRequests;
     Deque<Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>> m_pendingConnectionReplies;
index 2a78a6b..b9fcd19 100644 (file)
@@ -30,4 +30,8 @@ messages -> StorageProcessProxy LegacyReceiver {
 #if ENABLE(SANDBOX_EXTENSIONS)
     GetSandboxExtensionsForBlobFiles(uint64_t requestID, Vector<String> paths)
 #endif
+
+#if ENABLE(SERVICE_WORKER)
+    GetWorkerContextProcessConnection()
+#endif
 }
index 4b40def..025488b 100644 (file)
@@ -545,7 +545,7 @@ void WebProcessPool::ensureStorageProcessAndWebsiteDataStore(WebsiteDataStore* r
         }
 #endif
 
-        m_storageProcess = StorageProcessProxy::create(this);
+        m_storageProcess = StorageProcessProxy::create(*this);
         m_storageProcess->send(Messages::StorageProcess::InitializeWebsiteDataStore(parameters), 0);
     }
 
@@ -574,6 +574,29 @@ void WebProcessPool::storageProcessCrashed(StorageProcessProxy* storageProcessPr
     m_storageProcess = nullptr;
 }
 
+#if ENABLE(SERVICE_WORKER)
+void WebProcessPool::getWorkerContextProcessConnection(StorageProcessProxy& proxy)
+{
+    ASSERT_UNUSED(proxy, &proxy == m_storageProcess);
+    
+    if (!m_workerContextProcess) {
+        if (!m_websiteDataStore)
+            m_websiteDataStore = API::WebsiteDataStore::defaultDataStore().ptr();
+        auto& newProcess = createNewWebProcess(m_websiteDataStore->websiteDataStore());
+        m_workerContextProcess = &newProcess;
+    }
+    
+    m_workerContextProcess->send(Messages::WebProcess::GetWorkerContextConnection(), 0);
+}
+
+void WebProcessPool::didGetWorkerContextProcessConnection(const IPC::Attachment& connection)
+{
+    if (!m_storageProcess)
+        return;
+    m_storageProcess->didGetWorkerContextProcessConnection(connection);
+}
+#endif
+
 void WebProcessPool::willStartUsingPrivateBrowsing()
 {
     for (auto* processPool : allProcessPools())
@@ -882,6 +905,10 @@ void WebProcessPool::disconnectProcess(WebProcessProxy* process)
     RefPtr<WebProcessProxy> protect(process);
     if (m_processWithPageCache == process)
         m_processWithPageCache = nullptr;
+#if ENABLE(SERVICE_WORKER)
+    if (m_workerContextProcess == process)
+        m_workerContextProcess = nullptr;
+#endif
 
     static_cast<WebContextSupplement*>(supplement<WebGeolocationManagerProxy>())->processDidClose(process);
 
@@ -960,6 +987,8 @@ Ref<WebPageProxy> WebProcessPool::createWebPage(PageClient& pageClient, Ref<API:
     } else
         process = &createNewWebProcessRespectingProcessCountLimit(pageConfiguration->websiteDataStore()->websiteDataStore());
 
+    ASSERT(process.get() != m_workerContextProcess);
+
     return process->createWebPage(pageClient, WTFMove(pageConfiguration));
 }
 
index 7c7a8ec..1017ecb 100644 (file)
@@ -319,6 +319,9 @@ public:
     StorageProcessProxy* storageProcess() { return m_storageProcess.get(); }
     void getStorageProcessConnection(Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&&);
     void storageProcessCrashed(StorageProcessProxy*);
+#if ENABLE(SERVICE_WORKER)
+    void getWorkerContextProcessConnection(StorageProcessProxy&);
+#endif
 
 #if PLATFORM(COCOA)
     bool processSuppressionEnabled() const;
@@ -412,6 +415,10 @@ public:
     static uint64_t registerProcessPoolCreationListener(Function<void(WebProcessPool&)>&&);
     static void unregisterProcessPoolCreationListener(uint64_t identifier);
 
+#if ENABLE(SERVICE_WORKER)
+    void didGetWorkerContextProcessConnection(const IPC::Attachment& connection);
+#endif
+
 private:
     void platformInitialize();
 
@@ -477,6 +484,10 @@ private:
     bool m_haveInitialEmptyProcess;
 
     WebProcessProxy* m_processWithPageCache;
+#if ENABLE(SERVICE_WORKER)
+    WebProcessProxy* m_workerContextProcess { nullptr };
+    bool m_waitingForWorkerContextProcessConnection { false };
+#endif
 
     Ref<WebPageGroup> m_defaultPageGroup;
 
index d71d718..bc797c7 100644 (file)
@@ -1217,4 +1217,11 @@ const HashSet<String>& WebProcessProxy::platformPathsWithAssumedReadAccess()
 }
 #endif
 
+#if ENABLE(SERVICE_WORKER)
+void WebProcessProxy::didGetWorkerContextConnection(const IPC::Attachment& connection)
+{
+    m_processPool->didGetWorkerContextProcessConnection(connection);
+}
+#endif
+
 } // namespace WebKit
index 9622e47..42564f9 100644 (file)
@@ -181,6 +181,10 @@ public:
     bool isUnderMemoryPressure() const { return m_isUnderMemoryPressure; }
     void didExceedInactiveMemoryLimitWhileActive();
 
+#if ENABLE(SERVICE_WORKER)
+    void didGetWorkerContextConnection(const IPC::Attachment& connection);
+#endif
+
     void processTerminated();
 
     void didExceedCPULimit();
index ad69c52..191be4a 100644 (file)
@@ -54,4 +54,8 @@ messages -> WebProcessProxy LegacyReceiver {
 
     MemoryPressureStatusChanged(bool isUnderMemoryPressure)
     DidExceedInactiveMemoryLimitWhileActive()
+
+#if ENABLE(SERVICE_WORKER)
+    DidGetWorkerContextConnection(IPC::Attachment connection)
+#endif
 }
index c88c8f6..2f2facd 100644 (file)
@@ -42,6 +42,7 @@
 #include "PluginProcessConnectionManager.h"
 #include "SessionTracker.h"
 #include "StatisticsData.h"
+#include "StorageProcessMessages.h"
 #include "UserData.h"
 #include "WebAutomationSessionProxy.h"
 #include "WebCacheStorageProvider.h"
 #include <WebCore/RuntimeApplicationChecks.h>
 #include <WebCore/SchemeRegistry.h>
 #include <WebCore/SecurityOrigin.h>
+#include <WebCore/ServiceWorkerContextData.h>
 #include <WebCore/Settings.h>
 #include <WebCore/URLParser.h>
 #include <WebCore/UserGestureIndicator.h>
@@ -1614,4 +1616,44 @@ LibWebRTCNetwork& WebProcess::libWebRTCNetwork()
 }
 #endif
 
+#if ENABLE(SERVICE_WORKER)
+void WebProcess::getWorkerContextConnection()
+{
+    ASSERT(!m_workerContextConnection);
+
+#if USE(UNIX_DOMAIN_SOCKETS)
+    IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
+    IPC::Connection::Identifier connectionIdentifier(socketPair.server);
+    IPC::Attachment connectionClientPort(socketPair.client);
+#elif OS(DARWIN)
+    mach_port_t listeningPort;
+    if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort) != KERN_SUCCESS)
+        CRASH();
+
+    if (mach_port_insert_right(mach_task_self(), listeningPort, listeningPort, MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS)
+        CRASH();
+
+    IPC::Connection::Identifier connectionIdentifier(listeningPort);
+    IPC::Attachment connectionClientPort(listeningPort, MACH_MSG_TYPE_MOVE_SEND);
+#else
+    RELEASE_ASSERT_NOT_REACHED();
+#endif
+
+    m_workerContextConnection = IPC::Connection::createServerConnection(connectionIdentifier, *this);
+    m_workerContextConnection->open();
+
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::DidGetWorkerContextConnection(connectionClientPort), 0);
+}
+
+void WebProcess::startServiceWorkerContext(uint64_t serverConnectionIdentifier, const ServiceWorkerContextData& data)
+{
+    // FIXME: Here is where we will actually start the script.
+    // For now we bounce back a failure message to the requesting process for test coverage.
+
+    auto message = makeString("Failed to start service worker script of length ", String::number(data.script.length()));
+    m_workerContextConnection->send(Messages::StorageProcess::ServiceWorkerContextFailedToStart(serverConnectionIdentifier, data.registrationKey, data.workerID, message), 0);
+}
+
+#endif
+
 } // namespace WebKit
index 739a857..5c2e6c7 100644 (file)
@@ -71,6 +71,10 @@ class UserGestureToken;
 struct PluginInfo;
 struct SecurityOriginData;
 struct SoupNetworkProxySettings;
+
+#if ENABLE(SERVICE_WORKER)
+struct ServiceWorkerContextData;
+#endif
 }
 
 namespace WebKit {
@@ -290,10 +294,14 @@ private:
     void gamepadConnected(const GamepadData&);
     void gamepadDisconnected(unsigned index);
 #endif
-
 #if USE(SOUP)
     void setNetworkProxySettings(const WebCore::SoupNetworkProxySettings&);
 #endif
+#if ENABLE(SERVICE_WORKER)
+    void getWorkerContextConnection();
+    void startServiceWorkerContext(uint64_t serverConnectionIdentifier, const WebCore::ServiceWorkerContextData&);
+    RefPtr<IPC::Connection> m_workerContextConnection;
+#endif
 
     void releasePageCache();
 
index 08f6971..2206360 100644 (file)
@@ -113,4 +113,9 @@ messages -> WebProcess LegacyReceiver {
 #if USE(SOUP)
     SetNetworkProxySettings(struct WebCore::SoupNetworkProxySettings settings)
 #endif
+
+#if ENABLE(SERVICE_WORKER)
+    GetWorkerContextConnection()
+    StartServiceWorkerContext(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerContextData contextData)
+#endif
 }