Title: [229735] trunk
Revision
229735
Author
cdu...@apple.com
Date
2018-03-19 19:31:47 -0700 (Mon, 19 Mar 2018)

Log Message

Have one service worker process per security origin
https://bugs.webkit.org/show_bug.cgi?id=183600
<rdar://problem/35280128>

Reviewed by Brady Eidson.

Source/WebCore:

Split service workers from different origins into their own processes
for security reasons.

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::addRegistrationFromStore):
(WebCore::SWServer::clear):
(WebCore::SWServer::tryInstallContextData):
(WebCore::SWServer::serverToContextConnectionCreated):
(WebCore::SWServer::installContextData):
(WebCore::SWServer::runServiceWorkerIfNecessary):
(WebCore::SWServer::markAllWorkersAsTerminated):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerToContextConnection.cpp:
(WebCore::SWServerToContextConnection::SWServerToContextConnection):
(WebCore::SWServerToContextConnection::~SWServerToContextConnection):
(WebCore::SWServerToContextConnection::connectionForOrigin):
* workers/service/server/SWServerToContextConnection.h:
(WebCore::SWServerToContextConnection::origin):
* workers/service/server/SWServerWorker.cpp:
(WebCore::SWServerWorker::SWServerWorker):
(WebCore::SWServerWorker::securityOrigin const):
(WebCore::SWServerWorker::contextConnection):
* workers/service/server/SWServerWorker.h:

Source/WebKit:

Split service workers from different origins into their own processes
for security reasons.

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::startFetch):
(WebKit::WebSWServerConnection::postMessageToServiceWorker):
(WebKit::WebSWServerConnection::scheduleJobInServer):
* StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
(WebKit::WebSWServerToContextConnection::WebSWServerToContextConnection):
* StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
* StorageProcess/StorageProcess.cpp:
(WebKit::StorageProcess::connectionToContextProcessFromIPCConnection):
(WebKit::StorageProcess::didClose):
(WebKit::StorageProcess::connectionToContextProcessWasClosed):
(WebKit::StorageProcess::needsServerToContextConnectionForOrigin const):
(WebKit::StorageProcess::didReceiveMessage):
(WebKit::StorageProcess::createStorageToWebProcessConnection):
(WebKit::StorageProcess::serverToContextConnectionForOrigin):
(WebKit::StorageProcess::createServerToContextConnection):
* StorageProcess/StorageProcess.h:
* StorageProcess/StorageProcess.messages.in:
* StorageProcess/StorageToWebProcessConnection.cpp:
(WebKit::StorageToWebProcessConnection::didReceiveMessage):
(WebKit::StorageToWebProcessConnection::didClose):
* StorageProcess/StorageToWebProcessConnection.h:
* UIProcess/API/C/WKContext.cpp:
(WKContextTerminateServiceWorkerProcess):
* UIProcess/API/Cocoa/WKProcessPool.mm:
(-[WKProcessPool _terminateServiceWorkerProcesses]):
(-[WKProcessPool _webPageContentProcessCount]):
(-[WKProcessPool _serviceWorkerProcessCount]):
* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::didReceiveAuthenticationChallenge):
(WebKit::NetworkProcessProxy::canAuthenticateAgainstProtectionSpace):
* UIProcess/ServiceWorkerProcessProxy.cpp:
(WebKit::ServiceWorkerProcessProxy::create):
(WebKit::ServiceWorkerProcessProxy::ServiceWorkerProcessProxy):
* UIProcess/ServiceWorkerProcessProxy.h:
(isType):
* UIProcess/Storage/StorageProcessProxy.cpp:
(WebKit::StorageProcessProxy::getStorageProcessConnection):
(WebKit::StorageProcessProxy::didFinishLaunching):
(WebKit::StorageProcessProxy::establishWorkerContextConnectionToStorageProcess):
(WebKit::StorageProcessProxy::establishWorkerContextConnectionToStorageProcessForExplicitSession):
* UIProcess/Storage/StorageProcessProxy.h:
* UIProcess/Storage/StorageProcessProxy.messages.in:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::getStorageProcessConnection):
(WebKit::WebProcessPool::establishWorkerContextConnectionToStorageProcess):
(WebKit::WebProcessPool::createNewWebProcess):
(WebKit::WebProcessPool::disconnectProcess):
(WebKit::WebProcessPool::createNewWebProcessRespectingProcessCountLimit):
(WebKit::WebProcessPool::createWebPage):
(WebKit::WebProcessPool::updateServiceWorkerUserAgent):
(WebKit::WebProcessPool::mayHaveRegisteredServiceWorkers):
(WebKit::WebProcessPool::pageBeginUsingWebsiteDataStore):
(WebKit::WebProcessPool::terminateServiceWorkerProcesses):
(WebKit::WebProcessPool::updateProcessAssertions):
(WebKit::WebProcessPool::serviceWorkerProcessProxyFromPageID const):
* UIProcess/WebProcessPool.h:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::getStorageProcessConnection):

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (229734 => 229735)


--- trunk/Source/WebCore/ChangeLog	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebCore/ChangeLog	2018-03-20 02:31:47 UTC (rev 229735)
@@ -1,3 +1,35 @@
+2018-03-19  Chris Dumez  <cdu...@apple.com>
+
+        Have one service worker process per security origin
+        https://bugs.webkit.org/show_bug.cgi?id=183600
+        <rdar://problem/35280128>
+
+        Reviewed by Brady Eidson.
+
+        Split service workers from different origins into their own processes
+        for security reasons.
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::addRegistrationFromStore):
+        (WebCore::SWServer::clear):
+        (WebCore::SWServer::tryInstallContextData):
+        (WebCore::SWServer::serverToContextConnectionCreated):
+        (WebCore::SWServer::installContextData):
+        (WebCore::SWServer::runServiceWorkerIfNecessary):
+        (WebCore::SWServer::markAllWorkersAsTerminated):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerToContextConnection.cpp:
+        (WebCore::SWServerToContextConnection::SWServerToContextConnection):
+        (WebCore::SWServerToContextConnection::~SWServerToContextConnection):
+        (WebCore::SWServerToContextConnection::connectionForOrigin):
+        * workers/service/server/SWServerToContextConnection.h:
+        (WebCore::SWServerToContextConnection::origin):
+        * workers/service/server/SWServerWorker.cpp:
+        (WebCore::SWServerWorker::SWServerWorker):
+        (WebCore::SWServerWorker::securityOrigin const):
+        (WebCore::SWServerWorker::contextConnection):
+        * workers/service/server/SWServerWorker.h:
+
 2018-03-19  Megan Gardner  <megan_gard...@apple.com>
 
         Have select element respect current appearance

Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (229734 => 229735)


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -138,8 +138,7 @@
     auto registrationPtr = registration.get();
     addRegistration(WTFMove(registration));
 
-    auto* connection = SWServerToContextConnection::globalServerToContextConnection();
-    auto worker = SWServerWorker::create(*this, *registrationPtr, connection ? std::make_optional(connection->identifier()) : std::nullopt, data.scriptURL, data.script, data.contentSecurityPolicy, data.workerType, data.serviceWorkerIdentifier);
+    auto worker = SWServerWorker::create(*this, *registrationPtr, data.scriptURL, data.script, data.contentSecurityPolicy, data.workerType, data.serviceWorkerIdentifier);
     registrationPtr->updateRegistrationState(ServiceWorkerRegistrationState::Active, worker.ptr());
     worker->setState(ServiceWorkerState::Activated);
 }
@@ -226,9 +225,11 @@
             registrationsToRemove.append(keyAndValue.value.get());
     }
 
-    m_pendingContextDatas.removeAllMatching([&](auto& contextData) {
-        return contextData.registration.key.relatesToOrigin(origin);
-    });
+    for (auto& contextDatas : m_pendingContextDatas.values()) {
+        contextDatas.removeAllMatching([&](auto& contextData) {
+            return contextData.registration.key.relatesToOrigin(origin);
+        });
+    }
 
     if (registrationsToRemove.isEmpty()) {
         completionHandler();
@@ -497,11 +498,12 @@
 
 void SWServer::tryInstallContextData(ServiceWorkerContextData&& data)
 {
-    // Right now we only ever keep up to one connection to one SW context process.
-    // And it should always exist if we're trying to install context data.
-    auto* connection = SWServerToContextConnection::globalServerToContextConnection();
+    auto origin = SecurityOrigin::create(data.scriptURL);
+    auto* connection = SWServerToContextConnection::connectionForOrigin(origin);
     if (!connection) {
-        m_pendingContextDatas.append(WTFMove(data));
+        m_pendingContextDatas.ensure(WTFMove(origin), [] {
+            return Vector<ServiceWorkerContextData> { };
+        }).iterator->value.append(WTFMove(data));
         return;
     }
     
@@ -510,15 +512,11 @@
 
 void SWServer::serverToContextConnectionCreated(SWServerToContextConnection& contextConnection)
 {
-    // FIXME: This will need to update only workers using this connection once we use several context connections.
-    for (auto* worker : SWServerWorker::allWorkers().values())
-        worker->setContextConnectionIdentifier(contextConnection.identifier());
-
-    auto pendingContextDatas = WTFMove(m_pendingContextDatas);
+    auto pendingContextDatas = m_pendingContextDatas.take(&contextConnection.origin());
     for (auto& data : pendingContextDatas)
         installContextData(data);
 
-    auto serviceWorkerRunRequests = WTFMove(m_serviceWorkerRunRequests);
+    auto serviceWorkerRunRequests = m_serviceWorkerRunRequests.take(&contextConnection.origin());
     for (auto& item : serviceWorkerRunRequests) {
         bool success = runServiceWorker(item.key);
         for (auto& callback : item.value)
@@ -537,14 +535,14 @@
             return;
     }
 
-    auto* connection = SWServerToContextConnection::globalServerToContextConnection();
-    ASSERT(connection);
-
     auto* registration = m_registrations.get(data.registration.key);
     RELEASE_ASSERT(registration);
 
-    auto worker = SWServerWorker::create(*this, *registration, connection->identifier(), data.scriptURL, data.script, data.contentSecurityPolicy, data.workerType, data.serviceWorkerIdentifier);
+    auto worker = SWServerWorker::create(*this, *registration, data.scriptURL, data.script, data.contentSecurityPolicy, data.workerType, data.serviceWorkerIdentifier);
 
+    auto* connection = worker->contextConnection();
+    ASSERT(connection);
+
     registration->setPreInstallationWorker(worker.ptr());
     worker->setState(SWServerWorker::State::Running);
     auto result = m_runningOrTerminatingWorkers.add(data.serviceWorkerIdentifier, WTFMove(worker));
@@ -569,7 +567,10 @@
     }
 
     if (!contextConnection) {
-        m_serviceWorkerRunRequests.ensure(identifier, [&] {
+        auto& serviceWorkerRunRequestsForOrigin = m_serviceWorkerRunRequests.ensure(worker->securityOrigin(), [] {
+            return HashMap<ServiceWorkerIdentifier, Vector<RunServiceWorkerCallback>> { };
+        }).iterator->value;
+        serviceWorkerRunRequestsForOrigin.ensure(identifier, [&] {
             return Vector<RunServiceWorkerCallback> { };
         }).iterator->value.append(WTFMove(callback));
         return;
@@ -642,11 +643,8 @@
 
 void SWServer::markAllWorkersAsTerminated()
 {
-    while (!m_runningOrTerminatingWorkers.isEmpty()) {
-        auto& worker = m_runningOrTerminatingWorkers.begin()->value;
-        worker->setContextConnectionIdentifier(std::nullopt);
-        workerContextTerminated(worker);
-    }
+    while (!m_runningOrTerminatingWorkers.isEmpty())
+        workerContextTerminated(m_runningOrTerminatingWorkers.begin()->value);
 }
 
 void SWServer::workerContextTerminated(SWServerWorker& worker)

Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (229734 => 229735)


--- trunk/Source/WebCore/workers/service/server/SWServer.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -31,6 +31,7 @@
 #include "DocumentIdentifier.h"
 #include "RegistrationStore.h"
 #include "SWServerWorker.h"
+#include "SecurityOriginHash.h"
 #include "ServiceWorkerClientData.h"
 #include "ServiceWorkerIdentifier.h"
 #include "ServiceWorkerJob.h"
@@ -224,8 +225,8 @@
 
     UniqueRef<SWOriginStore> m_originStore;
     RegistrationStore m_registrationStore;
-    Vector<ServiceWorkerContextData> m_pendingContextDatas;
-    HashMap<ServiceWorkerIdentifier, Vector<RunServiceWorkerCallback>> m_serviceWorkerRunRequests;
+    HashMap<RefPtr<SecurityOrigin>, Vector<ServiceWorkerContextData>> m_pendingContextDatas;
+    HashMap<RefPtr<SecurityOrigin>, HashMap<ServiceWorkerIdentifier, Vector<RunServiceWorkerCallback>>> m_serviceWorkerRunRequests;
     PAL::SessionID m_sessionID;
     bool m_importCompleted { false };
     Vector<CompletionHandler<void()>> m_clearCompletionCallbacks;

Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp (229734 => 229735)


--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -30,6 +30,7 @@
 
 #include "SWServer.h"
 #include "SWServerWorker.h"
+#include "SecurityOriginHash.h"
 #include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
@@ -39,39 +40,31 @@
     return generateObjectIdentifier<SWServerToContextConnectionIdentifierType>();
 }
 
-static HashMap<SWServerToContextConnectionIdentifier, SWServerToContextConnection*>& allConnections()
+static HashMap<RefPtr<SecurityOrigin>, SWServerToContextConnection*>& allConnectionsByOrigin()
 {
-    static NeverDestroyed<HashMap<SWServerToContextConnectionIdentifier, SWServerToContextConnection*>> connections;
-    return connections;
+    static NeverDestroyed<HashMap<RefPtr<SecurityOrigin>, SWServerToContextConnection*>> connectionsByOrigin;
+    return connectionsByOrigin;
 }
 
-SWServerToContextConnection::SWServerToContextConnection()
+SWServerToContextConnection::SWServerToContextConnection(Ref<SecurityOrigin>&& origin)
     : m_identifier(generateServerToContextConnectionIdentifier())
+    , m_origin(WTFMove(origin))
 {
-    auto result = allConnections().add(m_identifier, this);
+    auto result = allConnectionsByOrigin().add(m_origin.copyRef(), this);
     ASSERT_UNUSED(result, result.isNewEntry);
 }
 
 SWServerToContextConnection::~SWServerToContextConnection()
 {
-    auto result = allConnections().remove(m_identifier);
+    auto result = allConnectionsByOrigin().remove(m_origin.ptr());
     ASSERT_UNUSED(result, result);
 }
 
-SWServerToContextConnection* SWServerToContextConnection::connectionForIdentifier(SWServerToContextConnectionIdentifier identifier)
+SWServerToContextConnection* SWServerToContextConnection::connectionForOrigin(const SecurityOrigin& origin)
 {
-    return allConnections().get(identifier);
+    return allConnectionsByOrigin().get(&const_cast<SecurityOrigin&>(origin));
 }
 
-SWServerToContextConnection* SWServerToContextConnection::globalServerToContextConnection()
-{
-    if (allConnections().isEmpty())
-        return nullptr;
-    
-    ASSERT(allConnections().size() == 1);
-    return allConnections().begin()->value;
-}
-
 void SWServerToContextConnection::scriptContextFailedToStart(const std::optional<ServiceWorkerJobDataIdentifier>& jobDataIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, const String& message)
 {
     if (auto* worker = SWServerWorker::existingWorkerForIdentifier(serviceWorkerIdentifier))

Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h (229734 => 229735)


--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -27,6 +27,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "SecurityOrigin.h"
 #include "ServiceWorkerClientQueryOptions.h"
 #include "ServiceWorkerIdentifier.h"
 #include "ServiceWorkerTypes.h"
@@ -73,17 +74,16 @@
     WEBCORE_EXPORT void matchAll(uint64_t requestIdentifier, ServiceWorkerIdentifier, const ServiceWorkerClientQueryOptions&);
     WEBCORE_EXPORT void claim(uint64_t requestIdentifier, ServiceWorkerIdentifier);
 
-    static SWServerToContextConnection* connectionForIdentifier(SWServerToContextConnectionIdentifier);
+    static SWServerToContextConnection* connectionForOrigin(const SecurityOrigin&);
 
-    // FIXME: While we only ever have one SW context process this method makes sense.
-    // Once we have multiple ones this method should go away forcing use of connectionForIdentifier()
-    WEBCORE_EXPORT static SWServerToContextConnection* globalServerToContextConnection();
+    SecurityOrigin& origin() { return m_origin.get(); }
 
 protected:
-    WEBCORE_EXPORT SWServerToContextConnection();
+    WEBCORE_EXPORT explicit SWServerToContextConnection(Ref<SecurityOrigin>&&);
 
 private:
     SWServerToContextConnectionIdentifier m_identifier;
+    Ref<SecurityOrigin> m_origin;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp (229734 => 229735)


--- trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -28,6 +28,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "SWServerToContextConnection.h"
 #include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
@@ -44,10 +45,9 @@
 }
 
 // FIXME: Use r-value references for script and contentSecurityPolicy
-SWServerWorker::SWServerWorker(SWServer& server, SWServerRegistration& registration, std::optional<SWServerToContextConnectionIdentifier> contextConnectionIdentifier, const URL& scriptURL, const String& script, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, WorkerType type, ServiceWorkerIdentifier identifier)
+SWServerWorker::SWServerWorker(SWServer& server, SWServerRegistration& registration, const URL& scriptURL, const String& script, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, WorkerType type, ServiceWorkerIdentifier identifier)
     : m_server(server)
     , m_registrationKey(registration.key())
-    , m_contextConnectionIdentifier(contextConnectionIdentifier)
     , m_data { identifier, scriptURL, ServiceWorkerState::Redundant, type, registration.identifier() }
     , m_script(script)
     , m_contentSecurityPolicy(contentSecurityPolicy)
@@ -90,12 +90,14 @@
     return *m_origin;
 }
 
+Ref<SecurityOrigin> SWServerWorker::securityOrigin() const
+{
+    return SecurityOrigin::create(m_data.scriptURL);
+}
+
 SWServerToContextConnection* SWServerWorker::contextConnection()
 {
-    if (!m_contextConnectionIdentifier)
-        return nullptr;
-
-    return SWServerToContextConnection::connectionForIdentifier(*m_contextConnectionIdentifier);
+    return SWServerToContextConnection::connectionForOrigin(securityOrigin());
 }
 
 void SWServerWorker::scriptContextFailedToStart(const std::optional<ServiceWorkerJobDataIdentifier>& jobDataIdentifier, const String& message)

Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.h (229734 => 229735)


--- trunk/Source/WebCore/workers/service/server/SWServerWorker.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -79,8 +79,6 @@
 
     ServiceWorkerIdentifier identifier() const { return m_data.identifier; }
 
-    void setContextConnectionIdentifier(std::optional<SWServerToContextConnectionIdentifier> identifier) { m_contextConnectionIdentifier = identifier; }
-
     ServiceWorkerState state() const { return m_data.state; }
     void setState(ServiceWorkerState);
 
@@ -104,18 +102,19 @@
 
     const ServiceWorkerData& data() const { return m_data; }
     ServiceWorkerContextData contextData() const;
+
     const ClientOrigin& origin() const;
+    WEBCORE_EXPORT Ref<SecurityOrigin> securityOrigin() const;
 
     WEBCORE_EXPORT SWServerToContextConnection* contextConnection();
 
 private:
-    SWServerWorker(SWServer&, SWServerRegistration&, std::optional<SWServerToContextConnectionIdentifier>, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&,  WorkerType, ServiceWorkerIdentifier);
+    SWServerWorker(SWServer&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&,  WorkerType, ServiceWorkerIdentifier);
 
     void callWhenActivatedHandler(bool success);
 
     SWServer& m_server;
     ServiceWorkerRegistrationKey m_registrationKey;
-    std::optional<SWServerToContextConnectionIdentifier> m_contextConnectionIdentifier;
     ServiceWorkerData m_data;
     String m_script;
     ContentSecurityPolicyResponseHeaders m_contentSecurityPolicy;

Modified: trunk/Source/WebKit/ChangeLog (229734 => 229735)


--- trunk/Source/WebKit/ChangeLog	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/ChangeLog	2018-03-20 02:31:47 UTC (rev 229735)
@@ -1,3 +1,75 @@
+2018-03-19  Chris Dumez  <cdu...@apple.com>
+
+        Have one service worker process per security origin
+        https://bugs.webkit.org/show_bug.cgi?id=183600
+        <rdar://problem/35280128>
+
+        Reviewed by Brady Eidson.
+
+        Split service workers from different origins into their own processes
+        for security reasons.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::startFetch):
+        (WebKit::WebSWServerConnection::postMessageToServiceWorker):
+        (WebKit::WebSWServerConnection::scheduleJobInServer):
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        (WebKit::WebSWServerToContextConnection::WebSWServerToContextConnection):
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * StorageProcess/StorageProcess.cpp:
+        (WebKit::StorageProcess::connectionToContextProcessFromIPCConnection):
+        (WebKit::StorageProcess::didClose):
+        (WebKit::StorageProcess::connectionToContextProcessWasClosed):
+        (WebKit::StorageProcess::needsServerToContextConnectionForOrigin const):
+        (WebKit::StorageProcess::didReceiveMessage):
+        (WebKit::StorageProcess::createStorageToWebProcessConnection):
+        (WebKit::StorageProcess::serverToContextConnectionForOrigin):
+        (WebKit::StorageProcess::createServerToContextConnection):
+        * StorageProcess/StorageProcess.h:
+        * StorageProcess/StorageProcess.messages.in:
+        * StorageProcess/StorageToWebProcessConnection.cpp:
+        (WebKit::StorageToWebProcessConnection::didReceiveMessage):
+        (WebKit::StorageToWebProcessConnection::didClose):
+        * StorageProcess/StorageToWebProcessConnection.h:
+        * UIProcess/API/C/WKContext.cpp:
+        (WKContextTerminateServiceWorkerProcess):
+        * UIProcess/API/Cocoa/WKProcessPool.mm:
+        (-[WKProcessPool _terminateServiceWorkerProcesses]):
+        (-[WKProcessPool _webPageContentProcessCount]):
+        (-[WKProcessPool _serviceWorkerProcessCount]):
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::didReceiveAuthenticationChallenge):
+        (WebKit::NetworkProcessProxy::canAuthenticateAgainstProtectionSpace):
+        * UIProcess/ServiceWorkerProcessProxy.cpp:
+        (WebKit::ServiceWorkerProcessProxy::create):
+        (WebKit::ServiceWorkerProcessProxy::ServiceWorkerProcessProxy):
+        * UIProcess/ServiceWorkerProcessProxy.h:
+        (isType):
+        * UIProcess/Storage/StorageProcessProxy.cpp:
+        (WebKit::StorageProcessProxy::getStorageProcessConnection):
+        (WebKit::StorageProcessProxy::didFinishLaunching):
+        (WebKit::StorageProcessProxy::establishWorkerContextConnectionToStorageProcess):
+        (WebKit::StorageProcessProxy::establishWorkerContextConnectionToStorageProcessForExplicitSession):
+        * UIProcess/Storage/StorageProcessProxy.h:
+        * UIProcess/Storage/StorageProcessProxy.messages.in:
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::getStorageProcessConnection):
+        (WebKit::WebProcessPool::establishWorkerContextConnectionToStorageProcess):
+        (WebKit::WebProcessPool::createNewWebProcess):
+        (WebKit::WebProcessPool::disconnectProcess):
+        (WebKit::WebProcessPool::createNewWebProcessRespectingProcessCountLimit):
+        (WebKit::WebProcessPool::createWebPage):
+        (WebKit::WebProcessPool::updateServiceWorkerUserAgent):
+        (WebKit::WebProcessPool::mayHaveRegisteredServiceWorkers):
+        (WebKit::WebProcessPool::pageBeginUsingWebsiteDataStore):
+        (WebKit::WebProcessPool::terminateServiceWorkerProcesses):
+        (WebKit::WebProcessPool::updateProcessAssertions):
+        (WebKit::WebProcessPool::serviceWorkerProcessProxyFromPageID const):
+        * UIProcess/WebProcessPool.h:
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::getStorageProcessConnection):
+
 2018-03-19  Jiewen Tan  <jiewen_...@apple.com>
 
         Unreviewed, another quick fix for r229699

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp (229734 => 229735)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -151,9 +151,15 @@
             return;
         }
 
-        if (!StorageProcess::singleton().globalServerToContextConnection())
-            StorageProcess::singleton().createServerToContextConnection(server().sessionID());
+        auto* worker = server().workerByID(serviceWorkerIdentifier);
+        if (!worker) {
+            m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
+            return;
+        }
 
+        if (!worker->contextConnection())
+            StorageProcess::singleton().createServerToContextConnection(worker->securityOrigin(), server().sessionID());
+
         server().runServiceWorkerIfNecessary(serviceWorkerIdentifier, [weakThis = WTFMove(weakThis), this, fetchIdentifier, serviceWorkerIdentifier, request = WTFMove(request), options = WTFMove(options), formData = WTFMove(formData), referrer = WTFMove(referrer)](auto* contextConnection) {
             if (!weakThis)
                 return;
@@ -178,15 +184,15 @@
 
 void WebSWServerConnection::postMessageToServiceWorker(ServiceWorkerIdentifier destinationIdentifier, MessageWithMessagePorts&& message, const ServiceWorkerOrClientIdentifier& sourceIdentifier)
 {
+    auto* destinationWorker = server().workerByID(destinationIdentifier);
+    if (!destinationWorker)
+        return;
+
     std::optional<ServiceWorkerOrClientData> sourceData;
     WTF::switchOn(sourceIdentifier, [&](ServiceWorkerIdentifier identifier) {
         if (auto* sourceWorker = server().workerByID(identifier))
             sourceData = ServiceWorkerOrClientData { sourceWorker->data() };
     }, [&](ServiceWorkerClientIdentifier identifier) {
-        auto* destinationWorker = server().workerByID(destinationIdentifier);
-        if (!destinationWorker)
-            return;
-
         if (auto clientData = destinationWorker->findClientByIdentifier(identifier))
             sourceData = ServiceWorkerOrClientData { *clientData };
     });
@@ -194,8 +200,8 @@
     if (!sourceData)
         return;
 
-    if (!StorageProcess::singleton().globalServerToContextConnection())
-        StorageProcess::singleton().createServerToContextConnection(server().sessionID());
+    if (!destinationWorker->contextConnection())
+        StorageProcess::singleton().createServerToContextConnection(destinationWorker->securityOrigin(), server().sessionID());
 
     // It's possible this specific worker cannot be re-run (e.g. its registration has been removed)
     server().runServiceWorkerIfNecessary(destinationIdentifier, [destinationIdentifier, message = WTFMove(message), sourceData = WTFMove(*sourceData)](auto* contextConnection) mutable {
@@ -206,8 +212,9 @@
 
 void WebSWServerConnection::scheduleJobInServer(ServiceWorkerJobData&& jobData)
 {
-    if (!StorageProcess::singleton().globalServerToContextConnection())
-        StorageProcess::singleton().createServerToContextConnection(server().sessionID());
+    auto securityOrigin = SecurityOrigin::create(jobData.scriptURL);
+    if (!StorageProcess::singleton().serverToContextConnectionForOrigin(securityOrigin))
+        StorageProcess::singleton().createServerToContextConnection(securityOrigin, server().sessionID());
 
     SWSERVERCONNECTION_RELEASE_LOG_IF_ALLOWED("Scheduling ServiceWorker job %s in server", jobData.identifier().loggingString().utf8().data());
     ASSERT(identifier() == jobData.connectionIdentifier());

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp (229734 => 229735)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -36,8 +36,9 @@
 
 namespace WebKit {
 
-WebSWServerToContextConnection::WebSWServerToContextConnection(Ref<IPC::Connection>&& connection)
-    : m_ipcConnection(WTFMove(connection))
+WebSWServerToContextConnection::WebSWServerToContextConnection(Ref<SecurityOrigin>&& origin, Ref<IPC::Connection>&& connection)
+    : SWServerToContextConnection(WTFMove(origin))
+    , m_ipcConnection(WTFMove(connection))
 {
 }
 

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h (229734 => 229735)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -48,7 +48,7 @@
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
 private:
-    explicit WebSWServerToContextConnection(Ref<IPC::Connection>&&);
+    explicit WebSWServerToContextConnection(Ref<WebCore::SecurityOrigin>&&, Ref<IPC::Connection>&&);
 
     // IPC::MessageSender
     IPC::Connection* messageSenderConnection() final;

Modified: trunk/Source/WebKit/StorageProcess/StorageProcess.cpp (229734 => 229735)


--- trunk/Source/WebKit/StorageProcess/StorageProcess.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/StorageProcess/StorageProcess.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -84,11 +84,22 @@
     return true;
 }
 
+#if ENABLE(SERVICE_WORKER)
+WebSWServerToContextConnection* StorageProcess::connectionToContextProcessFromIPCConnection(IPC::Connection& connection)
+{
+    for (auto& serverToContextConnection : m_serverToContextConnections.values()) {
+        if (serverToContextConnection->ipcConnection() == &connection)
+            return serverToContextConnection.ptr();
+    }
+    return nullptr;
+}
+#endif
+
 void StorageProcess::didClose(IPC::Connection& connection)
 {
 #if ENABLE(SERVICE_WORKER)
-    if (m_serverToContextConnection && m_serverToContextConnection->ipcConnection() == &connection) {
-        connectionToContextProcessWasClosed();
+    if (RefPtr<WebSWServerToContextConnection> serverToContextConnection = connectionToContextProcessFromIPCConnection(connection)) {
+        connectionToContextProcessWasClosed(serverToContextConnection.releaseNonNull());
         return;
     }
 #else
@@ -98,31 +109,31 @@
 }
 
 #if ENABLE(SERVICE_WORKER)
-void StorageProcess::connectionToContextProcessWasClosed()
+void StorageProcess::connectionToContextProcessWasClosed(Ref<WebSWServerToContextConnection>&& serverToContextConnection)
 {
-    if (!m_serverToContextConnection)
-        return;
+    Ref<SecurityOrigin> origin = serverToContextConnection->origin();
+    bool shouldRelaunch = needsServerToContextConnectionForOrigin(origin);
 
-    bool shouldRelaunch = needsServerToContextConnection();
+    serverToContextConnection->connectionClosed();
+    m_serverToContextConnections.remove(origin.ptr());
 
-    m_serverToContextConnection->connectionClosed();
-    m_serverToContextConnection = nullptr;
-
     for (auto& swServer : m_swServers.values())
         swServer->markAllWorkersAsTerminated();
 
     if (shouldRelaunch)
-        createServerToContextConnection(std::nullopt);
+        createServerToContextConnection(origin, std::nullopt);
 }
 
 // The rule is that we need a context process (and a connection to it) as long as we have SWServerConnections to regular WebProcesses.
-bool StorageProcess::needsServerToContextConnection() const
+bool StorageProcess::needsServerToContextConnectionForOrigin(SecurityOrigin& origin) const
 {
     if (m_swServerConnections.isEmpty())
         return false;
 
+    auto* contextConnection = m_serverToContextConnections.get(&origin);
+
     // If the last SWServerConnection is to the context process, then we no longer need the context connection.
-    if (m_swServerConnections.size() == 1 && m_serverToContextConnection && &m_swServerConnections.begin()->value->ipcConnection() == m_serverToContextConnection->ipcConnection())
+    if (m_swServerConnections.size() == 1 && contextConnection && &m_swServerConnections.begin()->value->ipcConnection() == contextConnection->ipcConnection())
         return false;
 
     return true;
@@ -149,8 +160,7 @@
         ASSERT(parentProcessHasServiceWorkerEntitlement());
         if (!parentProcessHasServiceWorkerEntitlement())
             return;
-        if (auto* swConnection = SWServerToContextConnection::globalServerToContextConnection()) {
-            auto* webSWConnection = static_cast<WebSWServerToContextConnection*>(swConnection);
+        if (auto* webSWConnection = connectionToContextProcessFromIPCConnection(connection)) {
             webSWConnection->didReceiveMessage(connection, decoder);
             return;
         }
@@ -244,7 +254,7 @@
     task.performTask();
 }
 
-void StorageProcess::createStorageToWebProcessConnection(bool isServiceWorkerProcess)
+void StorageProcess::createStorageToWebProcessConnection(bool isServiceWorkerProcess, WebCore::SecurityOriginData&& originData)
 {
 #if USE(UNIX_DOMAIN_SOCKETS)
     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
@@ -268,11 +278,15 @@
     if (isServiceWorkerProcess && !m_storageToWebProcessConnections.isEmpty()) {
         ASSERT(parentProcessHasServiceWorkerEntitlement());
         ASSERT(m_waitingForServerToContextProcessConnection);
-        m_serverToContextConnection = WebSWServerToContextConnection::create(m_storageToWebProcessConnections.last()->connection());
+        auto origin = originData.securityOrigin();
+        auto contextConnection = WebSWServerToContextConnection::create(origin.copyRef(), m_storageToWebProcessConnections.last()->connection());
+        auto addResult = m_serverToContextConnections.add(WTFMove(origin), contextConnection.copyRef());
+        ASSERT_UNUSED(addResult, addResult.isNewEntry);
+
         m_waitingForServerToContextProcessConnection = false;
 
         for (auto* server : SWServer::allServers())
-            server->serverToContextConnectionCreated(*m_serverToContextConnection);
+            server->serverToContextConnectionCreated(contextConnection);
     }
 #else
     UNUSED_PARAM(isServiceWorkerProcess);
@@ -438,12 +452,12 @@
     return static_cast<WebSWOriginStore&>(swServerForSession(sessionID).originStore());
 }
 
-WebSWServerToContextConnection* StorageProcess::globalServerToContextConnection()
+WebSWServerToContextConnection* StorageProcess::serverToContextConnectionForOrigin(const WebCore::SecurityOrigin& origin)
 {
-    return m_serverToContextConnection.get();
+    return m_serverToContextConnections.get(&const_cast<SecurityOrigin&>(origin));
 }
 
-void StorageProcess::createServerToContextConnection(std::optional<PAL::SessionID> sessionID)
+void StorageProcess::createServerToContextConnection(const SecurityOrigin& origin, std::optional<PAL::SessionID> sessionID)
 {
     if (m_waitingForServerToContextProcessConnection)
         return;
@@ -450,9 +464,9 @@
     
     m_waitingForServerToContextProcessConnection = true;
     if (sessionID)
-        parentProcessConnection()->send(Messages::StorageProcessProxy::EstablishWorkerContextConnectionToStorageProcessForExplicitSession(*sessionID), 0);
+        parentProcessConnection()->send(Messages::StorageProcessProxy::EstablishWorkerContextConnectionToStorageProcessForExplicitSession(SecurityOriginData::fromSecurityOrigin(origin), *sessionID), 0);
     else
-        parentProcessConnection()->send(Messages::StorageProcessProxy::EstablishWorkerContextConnectionToStorageProcess(), 0);
+        parentProcessConnection()->send(Messages::StorageProcessProxy::EstablishWorkerContextConnectionToStorageProcess(SecurityOriginData::fromSecurityOrigin(origin)), 0);
 }
 
 void StorageProcess::didFailFetch(SWServerConnectionIdentifier serverConnectionIdentifier, uint64_t fetchIdentifier)

Modified: trunk/Source/WebKit/StorageProcess/StorageProcess.h (229734 => 229735)


--- trunk/Source/WebKit/StorageProcess/StorageProcess.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/StorageProcess/StorageProcess.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -29,6 +29,7 @@
 #include "SandboxExtension.h"
 #include <WebCore/IDBBackingStore.h>
 #include <WebCore/IDBServer.h>
+#include <WebCore/SecurityOriginHash.h>
 #include <WebCore/ServiceWorkerIdentifier.h>
 #include <WebCore/ServiceWorkerTypes.h>
 #include <WebCore/UniqueIDBDatabase.h>
@@ -93,10 +94,8 @@
 #endif
 
 #if ENABLE(SERVICE_WORKER)
-    // For now we just have one global connection to service worker context processes.
-    // This will change in the future.
-    WebSWServerToContextConnection* globalServerToContextConnection();
-    void createServerToContextConnection(std::optional<PAL::SessionID>);
+    WebSWServerToContextConnection* serverToContextConnectionForOrigin(const WebCore::SecurityOrigin&);
+    void createServerToContextConnection(const WebCore::SecurityOrigin&, std::optional<PAL::SessionID>);
 
     WebCore::SWServer& swServerForSession(PAL::SessionID);
     void registerSWServerConnection(WebSWServerConnection&);
@@ -106,7 +105,8 @@
     void didReceiveStorageProcessMessage(IPC::Connection&, IPC::Decoder&);
 
 #if ENABLE(SERVICE_WORKER)
-    void connectionToContextProcessWasClosed();
+    WebSWServerToContextConnection* connectionToContextProcessFromIPCConnection(IPC::Connection&);
+    void connectionToContextProcessWasClosed(Ref<WebSWServerToContextConnection>&&);
 #endif
 
 private:
@@ -125,7 +125,7 @@
 
     // Message Handlers
     void initializeWebsiteDataStore(const StorageProcessCreationParameters&);
-    void createStorageToWebProcessConnection(bool isServiceWorkerProcess);
+    void createStorageToWebProcessConnection(bool isServiceWorkerProcess, WebCore::SecurityOriginData&&);
 
     void fetchWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType> websiteDataTypes, uint64_t callbackID);
     void deleteWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType> websiteDataTypes, WallTime modifiedSince, uint64_t callbackID);
@@ -146,7 +146,7 @@
     void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&&, const WebCore::ServiceWorkerOrClientIdentifier& source, WebCore::SWServerConnectionIdentifier);
 
     WebSWOriginStore& swOriginStoreForSession(PAL::SessionID);
-    bool needsServerToContextConnection() const;
+    bool needsServerToContextConnectionForOrigin(WebCore::SecurityOrigin&) const;
 #endif
 #if ENABLE(INDEXED_DATABASE)
     Vector<WebCore::SecurityOriginData> indexedDatabaseOrigins(const String& path);
@@ -173,7 +173,7 @@
 #if ENABLE(SERVICE_WORKER)
     void didCreateWorkerContextProcessConnection(const IPC::Attachment&);
 
-    RefPtr<WebSWServerToContextConnection> m_serverToContextConnection;
+    HashMap<RefPtr<WebCore::SecurityOrigin>, Ref<WebSWServerToContextConnection>> m_serverToContextConnections;
     bool m_waitingForServerToContextProcessConnection { false };
     HashMap<PAL::SessionID, String> m_swDatabasePaths;
     HashMap<PAL::SessionID, std::unique_ptr<WebCore::SWServer>> m_swServers;

Modified: trunk/Source/WebKit/StorageProcess/StorageProcess.messages.in (229734 => 229735)


--- trunk/Source/WebKit/StorageProcess/StorageProcess.messages.in	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/StorageProcess/StorageProcess.messages.in	2018-03-20 02:31:47 UTC (rev 229735)
@@ -25,7 +25,7 @@
     InitializeWebsiteDataStore(struct WebKit::StorageProcessCreationParameters processCreationParameters)
 
     # Creates a connection for communication with a WebProcess
-    CreateStorageToWebProcessConnection(bool isServiceWorkerProcess)
+    CreateStorageToWebProcessConnection(bool isServiceWorkerProcess, struct WebCore::SecurityOriginData origin)
 
     FetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebKit::WebsiteDataType> websiteDataTypes, uint64_t callbackID)
     DeleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebKit::WebsiteDataType> websiteDataTypes, WallTime modifiedSince, uint64_t callbackID)

Modified: trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.cpp (229734 => 229735)


--- trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -93,8 +93,10 @@
     }
 
     if (decoder.messageReceiverName() == Messages::WebSWServerToContextConnection::messageReceiverName()) {
-        StorageProcess::singleton().globalServerToContextConnection()->didReceiveMessage(connection, decoder);
-        return;
+        if (auto* contextConnection = StorageProcess::singleton().connectionToContextProcessFromIPCConnection(connection)) {
+            contextConnection->didReceiveMessage(connection, decoder);
+            return;
+        }
     }
 #endif
 
@@ -125,9 +127,10 @@
     UNUSED_PARAM(connection);
 
 #if ENABLE(SERVICE_WORKER)
-    if (StorageProcess::singleton().globalServerToContextConnection() && StorageProcess::singleton().globalServerToContextConnection()->ipcConnection() == &connection) {
+    if (RefPtr<WebSWServerToContextConnection> serverToContextConnection = StorageProcess::singleton().connectionToContextProcessFromIPCConnection(connection)) {
         // Service Worker process exited.
-        StorageProcess::singleton().connectionToContextProcessWasClosed();
+        StorageProcess::singleton().connectionToContextProcessWasClosed(serverToContextConnection.releaseNonNull());
+        return;
     }
 #endif
 

Modified: trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.h (229734 => 229735)


--- trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/StorageProcess/StorageToWebProcessConnection.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -36,6 +36,7 @@
 
 class WebIDBConnectionToClient;
 class WebSWServerConnection;
+class WebSWServerToContextConnection;
 
 class StorageToWebProcessConnection : public RefCounted<StorageToWebProcessConnection>, private IPC::Connection::Client, private IPC::MessageSender {
 public:

Modified: trunk/Source/WebKit/UIProcess/API/C/WKContext.cpp (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/API/C/WKContext.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/API/C/WKContext.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -608,7 +608,7 @@
 
 void WKContextTerminateServiceWorkerProcess(WKContextRef context)
 {
-    toImpl(context)->terminateServiceWorkerProcess();
+    toImpl(context)->terminateServiceWorkerProcesses();
 }
 
 ProcessID WKContextGetNetworkProcessIdentifier(WKContextRef contextRef)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2018-03-20 02:31:47 UTC (rev 229735)
@@ -424,9 +424,9 @@
     _processPool->terminateNetworkProcess();
 }
 
-- (void)_terminateServiceWorkerProcess
+- (void)_terminateServiceWorkerProcesses
 {
-    _processPool->terminateServiceWorkerProcess();
+    _processPool->terminateServiceWorkerProcesses();
 }
 
 - (pid_t)_networkProcessIdentifier
@@ -453,24 +453,11 @@
 {
     auto allWebProcesses = _processPool->processes();
 #if ENABLE(SERVICE_WORKER)
-    auto* serviceWorkerProcess = _processPool->serviceWorkerProxy();
-    if (!serviceWorkerProcess)
+    auto& serviceWorkerProcesses = _processPool->serviceWorkerProxies();
+    if (serviceWorkerProcesses.isEmpty())
         return allWebProcesses.size();
 
-#if !ASSERT_DISABLED
-    bool serviceWorkerProcessWasFound = false;
-    for (auto& process : allWebProcesses) {
-        if (process == serviceWorkerProcess) {
-            serviceWorkerProcessWasFound = true;
-            break;
-        }
-    }
-
-    ASSERT(serviceWorkerProcessWasFound);
-    ASSERT(allWebProcesses.size() > 1);
-#endif
-
-    return allWebProcesses.size() - 1;
+    return allWebProcesses.size() - serviceWorkerProcesses.size();
 #else
     return allWebProcesses.size();
 #endif
@@ -490,6 +477,15 @@
 #endif
 }
 
+- (size_t)_serviceWorkerProcessCount
+{
+#if ENABLE(SERVICE_WORKER)
+    return _processPool->serviceWorkerProxies().size();
+#else
+    return 0;
+#endif
+}
+
 + (void)_forceGameControllerFramework
 {
 #if ENABLE(GAMEPAD)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -78,7 +78,7 @@
 // Test only. Should be called only while no web content processes are running.
 - (void)_terminateStorageProcess;
 - (void)_terminateNetworkProcess;
-- (void)_terminateServiceWorkerProcess;
+- (void)_terminateServiceWorkerProcesses WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 // Test only.
 - (pid_t)_networkProcessIdentifier WK_API_AVAILABLE(macosx(10.13), ios(11.0));
@@ -87,6 +87,7 @@
 // Test only.
 - (size_t)_webProcessCount WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 - (size_t)_pluginProcessCount WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (size_t)_serviceWorkerProcessCount WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (void)_syncNetworkProcessCookies WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 
 // Test only. Returns web processes running web pages (does not include web processes running service workers)

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -276,9 +276,9 @@
 void NetworkProcessProxy::didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, const WebCore::AuthenticationChallenge& coreChallenge, uint64_t challengeID)
 {
 #if ENABLE(SERVICE_WORKER)
-    if (m_processPool.isServiceWorker(pageID)) {
+    if (auto* serviceWorkerProcessProxy = m_processPool.serviceWorkerProcessProxyFromPageID(pageID)) {
         auto authenticationChallenge = AuthenticationChallengeProxy::create(coreChallenge, challengeID, connection());
-        m_processPool.serviceWorkerProxy()->didReceiveAuthenticationChallenge(pageID, frameID, WTFMove(authenticationChallenge));
+        serviceWorkerProcessProxy->didReceiveAuthenticationChallenge(pageID, frameID, WTFMove(authenticationChallenge));
         return;
     }
 #endif
@@ -394,7 +394,7 @@
             return;
         }
 #if ENABLE(SERVICE_WORKER)
-    } else if (m_processPool.isServiceWorker(pageID)) {
+    } else if (m_processPool.serviceWorkerProcessProxyFromPageID(pageID)) {
         send(Messages::NetworkProcess::ContinueCanAuthenticateAgainstProtectionSpace(loaderID, true), 0);
         return;
 #endif

Modified: trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -40,15 +40,18 @@
 
 namespace WebKit {
 
-Ref<ServiceWorkerProcessProxy> ServiceWorkerProcessProxy::create(WebProcessPool& pool, WebsiteDataStore& store)
+using namespace WebCore;
+
+Ref<ServiceWorkerProcessProxy> ServiceWorkerProcessProxy::create(WebProcessPool& pool, Ref<SecurityOrigin>&& origin, WebsiteDataStore& store)
 {
-    auto proxy = adoptRef(*new ServiceWorkerProcessProxy { pool, store });
+    auto proxy = adoptRef(*new ServiceWorkerProcessProxy { pool, WTFMove(origin), store });
     proxy->connect();
     return proxy;
 }
 
-ServiceWorkerProcessProxy::ServiceWorkerProcessProxy(WebProcessPool& pool, WebsiteDataStore& store)
+ServiceWorkerProcessProxy::ServiceWorkerProcessProxy(WebProcessPool& pool, Ref<SecurityOrigin>&& origin, WebsiteDataStore& store)
     : WebProcessProxy { pool, store }
+    , m_origin(WTFMove(origin))
     , m_serviceWorkerPageID(generatePageID())
 {
 }

Modified: trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.h (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -28,6 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "WebProcessProxy.h"
+#include <WebCore/SecurityOrigin.h>
 
 namespace WebKit {
 class AuthenticationChallengeProxy;
@@ -35,7 +36,7 @@
 
 class ServiceWorkerProcessProxy final : public WebProcessProxy {
 public:
-    static Ref<ServiceWorkerProcessProxy> create(WebProcessPool&, WebsiteDataStore&);
+    static Ref<ServiceWorkerProcessProxy> create(WebProcessPool&, Ref<WebCore::SecurityOrigin>&&, WebsiteDataStore&);
     ~ServiceWorkerProcessProxy();
 
     static bool hasRegisteredServiceWorkers(const String& serviceWorkerDirectory);
@@ -46,6 +47,7 @@
     void setUserAgent(const String&);
     void updatePreferencesStore(const WebPreferencesStore&);
 
+    WebCore::SecurityOrigin& origin() { return m_origin.get(); }
     uint64_t pageID() const { return m_serviceWorkerPageID; }
 
 private:
@@ -54,10 +56,16 @@
 
     bool isServiceWorkerProcess() const final { return true; }
 
-    ServiceWorkerProcessProxy(WebProcessPool&, WebsiteDataStore&);
+    ServiceWorkerProcessProxy(WebProcessPool&, Ref<WebCore::SecurityOrigin>&&, WebsiteDataStore&);
+
+    Ref<WebCore::SecurityOrigin> m_origin;
     uint64_t m_serviceWorkerPageID { 0 };
 };
 
 } // namespace WebKit
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebKit::ServiceWorkerProcessProxy)
+    static bool isType(const WebKit::WebProcessProxy& webProcessProxy) { return webProcessProxy.isServiceWorkerProcess(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.cpp (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -27,6 +27,7 @@
 #include "StorageProcessProxy.h"
 
 #include "NetworkProcessMessages.h"
+#include "ServiceWorkerProcessProxy.h"
 #include "StorageProcessMessages.h"
 #include "StorageProcessProxyMessages.h"
 #include "WebProcessPool.h"
@@ -111,7 +112,7 @@
     send(Messages::StorageProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, origins, callbackID), 0);
 }
 
-void StorageProcessProxy::getStorageProcessConnection(bool isServiceWorkerProcess, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&& reply)
+void StorageProcessProxy::getStorageProcessConnection(WebProcessProxy& webProcessProxy, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&& reply)
 {
     m_pendingConnectionReplies.append(WTFMove(reply));
 
@@ -120,7 +121,16 @@
         return;
     }
 
-    send(Messages::StorageProcess::CreateStorageToWebProcessConnection(isServiceWorkerProcess), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+    bool isServiceWorkerProcess = false;
+    SecurityOriginData origin;
+#if ENABLE(SERVICE_WORKER)
+    if (is<ServiceWorkerProcessProxy>(webProcessProxy)) {
+        isServiceWorkerProcess = true;
+        origin = SecurityOriginData::fromSecurityOrigin(downcast<ServiceWorkerProcessProxy>(webProcessProxy).origin());
+    }
+#endif
+
+    send(Messages::StorageProcess::CreateStorageToWebProcessConnection(isServiceWorkerProcess, origin), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 }
 
 void StorageProcessProxy::didClose(IPC::Connection&)
@@ -215,20 +225,20 @@
     }
 
     for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i)
-        send(Messages::StorageProcess::CreateStorageToWebProcessConnection(false), 0);
+        send(Messages::StorageProcess::CreateStorageToWebProcessConnection(false, { }), 0);
     
     m_numPendingConnectionRequests = 0;
 }
 
 #if ENABLE(SERVICE_WORKER)
-void StorageProcessProxy::establishWorkerContextConnectionToStorageProcess()
+void StorageProcessProxy::establishWorkerContextConnectionToStorageProcess(SecurityOriginData&& origin)
 {
-    m_processPool.establishWorkerContextConnectionToStorageProcess(*this, std::nullopt);
+    m_processPool.establishWorkerContextConnectionToStorageProcess(*this, WTFMove(origin), std::nullopt);
 }
 
-void StorageProcessProxy::establishWorkerContextConnectionToStorageProcessForExplicitSession(PAL::SessionID sessionID)
+void StorageProcessProxy::establishWorkerContextConnectionToStorageProcessForExplicitSession(SecurityOriginData&& origin, PAL::SessionID sessionID)
 {
-    m_processPool.establishWorkerContextConnectionToStorageProcess(*this, sessionID);
+    m_processPool.establishWorkerContextConnectionToStorageProcess(*this, WTFMove(origin), sessionID);
 }
 #endif
 

Modified: trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.h (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -43,6 +43,7 @@
 namespace WebKit {
 
 class WebProcessPool;
+class WebProcessProxy;
 enum class WebsiteDataType;
 struct WebsiteData;
 
@@ -55,7 +56,7 @@
     void deleteWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, WallTime modifiedSince, WTF::Function<void()>&& completionHandler);
     void deleteWebsiteDataForOrigins(PAL::SessionID, OptionSet<WebsiteDataType>, const Vector<WebCore::SecurityOriginData>&, WTF::Function<void()>&& completionHandler);
 
-    void getStorageProcessConnection(bool isServiceWorkerProcess, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&&);
+    void getStorageProcessConnection(WebProcessProxy&, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&&);
 
 private:
     StorageProcessProxy(WebProcessPool&);
@@ -80,8 +81,8 @@
     void getSandboxExtensionsForBlobFiles(uint64_t requestID, const Vector<String>& paths);
 #endif
 #if ENABLE(SERVICE_WORKER)
-    void establishWorkerContextConnectionToStorageProcess();
-    void establishWorkerContextConnectionToStorageProcessForExplicitSession(PAL::SessionID);
+    void establishWorkerContextConnectionToStorageProcess(WebCore::SecurityOriginData&&);
+    void establishWorkerContextConnectionToStorageProcessForExplicitSession(WebCore::SecurityOriginData&&, PAL::SessionID);
 #endif
 
     // ProcessLauncher::Client

Modified: trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.messages.in (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.messages.in	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/Storage/StorageProcessProxy.messages.in	2018-03-20 02:31:47 UTC (rev 229735)
@@ -32,7 +32,7 @@
 #endif
 
 #if ENABLE(SERVICE_WORKER)
-    EstablishWorkerContextConnectionToStorageProcess()
-    EstablishWorkerContextConnectionToStorageProcessForExplicitSession(PAL::SessionID explicitSession)
+    EstablishWorkerContextConnectionToStorageProcess(struct WebCore::SecurityOriginData origin)
+    EstablishWorkerContextConnectionToStorageProcessForExplicitSession(struct WebCore::SecurityOriginData origin, PAL::SessionID explicitSession)
 #endif
 }

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -236,7 +236,7 @@
     , m_processSuppressionDisabledForPageCounter([this](RefCounterEvent) { updateProcessSuppressionState(); })
     , m_hiddenPageThrottlingAutoIncreasesCounter([this](RefCounterEvent) { m_hiddenPageThrottlingTimer.startOneShot(0_s); })
     , m_hiddenPageThrottlingTimer(RunLoop::main(), this, &WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit)
-    , m_serviceWorkerProcessTerminationTimer(RunLoop::main(), this, &WebProcessPool::terminateServiceWorkerProcess)
+    , m_serviceWorkerProcessesTerminationTimer(RunLoop::main(), this, &WebProcessPool::terminateServiceWorkerProcesses)
 #if PLATFORM(IOS)
     , m_foregroundWebProcessCounter([this](RefCounterEvent) { updateProcessAssertions(); })
     , m_backgroundWebProcessCounter([this](RefCounterEvent) { updateProcessAssertions(); })
@@ -569,11 +569,11 @@
     m_storageProcess->send(Messages::StorageProcess::InitializeWebsiteDataStore(relevantDataStore->storageProcessParameters()), 0);
 }
 
-void WebProcessPool::getStorageProcessConnection(bool isServiceWorkerProcess, PAL::SessionID initialSessionID, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&& reply)
+void WebProcessPool::getStorageProcessConnection(WebProcessProxy& webProcessProxy, PAL::SessionID initialSessionID, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&& reply)
 {
     ensureStorageProcessAndWebsiteDataStore(WebsiteDataStore::existingNonDefaultDataStoreForSessionID(initialSessionID));
 
-    m_storageProcess->getStorageProcessConnection(isServiceWorkerProcess, WTFMove(reply));
+    m_storageProcess->getStorageProcessConnection(webProcessProxy, WTFMove(reply));
 }
 
 void WebProcessPool::storageProcessCrashed(StorageProcessProxy* storageProcessProxy)
@@ -589,11 +589,12 @@
 }
 
 #if ENABLE(SERVICE_WORKER)
-void WebProcessPool::establishWorkerContextConnectionToStorageProcess(StorageProcessProxy& proxy, std::optional<PAL::SessionID> sessionID)
+void WebProcessPool::establishWorkerContextConnectionToStorageProcess(StorageProcessProxy& proxy, SecurityOriginData&& originData, std::optional<PAL::SessionID> sessionID)
 {
     ASSERT_UNUSED(proxy, &proxy == m_storageProcess);
 
-    if (m_serviceWorkerProcess)
+    auto origin = originData.securityOrigin();
+    if (m_serviceWorkerProcesses.contains(origin.ptr()))
         return;
 
     m_mayHaveRegisteredServiceWorkers.clear();
@@ -608,20 +609,22 @@
         websiteDataStore = &m_websiteDataStore->websiteDataStore();
     }
 
-    auto serviceWorkerProcessProxy = ServiceWorkerProcessProxy::create(*this, *websiteDataStore);
-    m_serviceWorkerProcess = serviceWorkerProcessProxy.ptr();
+    auto serviceWorkerProcessProxy = ServiceWorkerProcessProxy::create(*this, origin.copyRef(), *websiteDataStore);
+    m_serviceWorkerProcesses.add(origin.copyRef(), serviceWorkerProcessProxy.ptr());
+
     ASSERT(websiteDataStore->sessionID().isValid());
     if (websiteDataStore->sessionID().isValid())
         sendToAllProcesses(Messages::WebProcess::RegisterServiceWorkerClients { websiteDataStore->sessionID() });
 
     updateProcessAssertions();
-    initializeNewWebProcess(serviceWorkerProcessProxy.get(), *websiteDataStore);
+    initializeNewWebProcess(serviceWorkerProcessProxy, *websiteDataStore);
 
+    auto* serviceWorkerProcessProxyPtr = serviceWorkerProcessProxy.ptr();
     m_processes.append(WTFMove(serviceWorkerProcessProxy));
 
-    m_serviceWorkerProcess->start(m_serviceWorkerPreferences ? m_serviceWorkerPreferences.value() : m_defaultPageGroup->preferences().store(), sessionID);
+    serviceWorkerProcessProxyPtr->start(m_serviceWorkerPreferences ? m_serviceWorkerPreferences.value() : m_defaultPageGroup->preferences().store(), sessionID);
     if (!m_serviceWorkerUserAgent.isNull())
-        m_serviceWorkerProcess->setUserAgent(m_serviceWorkerUserAgent);
+        serviceWorkerProcessProxyPtr->setUserAgent(m_serviceWorkerUserAgent);
 }
 #endif
 
@@ -709,8 +712,8 @@
     initializeNewWebProcess(process, websiteDataStore);
     m_processes.append(WTFMove(processProxy));
 
-    if (m_serviceWorkerProcessTerminationTimer.isActive())
-        m_serviceWorkerProcessTerminationTimer.stop();
+    if (m_serviceWorkerProcessesTerminationTimer.isActive())
+        m_serviceWorkerProcessesTerminationTimer.stop();
 
     return process;
 }
@@ -970,9 +973,11 @@
     RefPtr<WebProcessProxy> protect(process);
     if (m_processWithPageCache == process)
         m_processWithPageCache = nullptr;
+
 #if ENABLE(SERVICE_WORKER)
-    if (m_serviceWorkerProcess == process) {
-        m_serviceWorkerProcess = nullptr;
+    if (is<ServiceWorkerProcessProxy>(*process)) {
+        auto* removedProcess = m_serviceWorkerProcesses.take(&downcast<ServiceWorkerProcessProxy>(*process).origin());
+        ASSERT_UNUSED(removedProcess, removedProcess == process);
         updateProcessAssertions();
     }
 #endif
@@ -989,9 +994,9 @@
 #if ENABLE(SERVICE_WORKER)
     // FIXME: We should do better than this. For now, we just destroy the ServiceWorker process
     // whenever there is no regular WebContent process remaining.
-    if (m_processes.size() == 1 && m_processes[0] == m_serviceWorkerProcess) {
-        if (!m_serviceWorkerProcessTerminationTimer.isActive())
-            m_serviceWorkerProcessTerminationTimer.startOneShot(serviceWorkerTerminationDelay);
+    if (m_processes.size() == m_serviceWorkerProcesses.size()) {
+        if (!m_serviceWorkerProcessesTerminationTimer.isActive())
+            m_serviceWorkerProcessesTerminationTimer.startOneShot(serviceWorkerTerminationDelay);
     }
 #endif
 }
@@ -1015,7 +1020,7 @@
         if (mustMatchDataStore && &process->websiteDataStore() != &websiteDataStore)
             continue;
 #if ENABLE(SERVICE_WORKER)
-        if (process.get() == m_serviceWorkerProcess)
+        if (is<ServiceWorkerProcessProxy>(*process))
             continue;
 #endif
         // Choose the process with fewest pages.
@@ -1058,7 +1063,7 @@
         process = &createNewWebProcessRespectingProcessCountLimit(pageConfiguration->websiteDataStore()->websiteDataStore());
 
 #if ENABLE(SERVICE_WORKER)
-    ASSERT(process.get() != m_serviceWorkerProcess);
+    ASSERT(!is<ServiceWorkerProcessProxy>(*process));
 #endif
 
     return process->createWebPage(pageClient, WTFMove(pageConfiguration));
@@ -1070,13 +1075,13 @@
     if (m_serviceWorkerUserAgent == userAgent)
         return;
     m_serviceWorkerUserAgent = userAgent;
-    if (m_serviceWorkerProcess)
-        m_serviceWorkerProcess->setUserAgent(m_serviceWorkerUserAgent);
+    for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values())
+        serviceWorkerProcess->setUserAgent(m_serviceWorkerUserAgent);
 }
 
 bool WebProcessPool::mayHaveRegisteredServiceWorkers(const WebsiteDataStore& store)
 {
-    if (serviceWorkerProxy())
+    if (!m_serviceWorkerProcesses.isEmpty())
         return true;
 
     String serviceWorkerRegistrationDirectory = store.resolvedServiceWorkerRegistrationDirectory();
@@ -1113,8 +1118,8 @@
 #if ENABLE(SERVICE_WORKER)
     if (!m_serviceWorkerPreferences) {
         m_serviceWorkerPreferences = page.preferencesStore();
-        if (m_serviceWorkerProcess)
-            m_serviceWorkerProcess->updatePreferencesStore(m_serviceWorkerPreferences.value());
+        for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values())
+            serviceWorkerProcess->updatePreferencesStore(*m_serviceWorkerPreferences);
     }
 #endif
 }
@@ -1497,19 +1502,15 @@
     m_didNetworkProcessCrash = true;
 }
 
-void WebProcessPool::terminateServiceWorkerProcess()
+void WebProcessPool::terminateServiceWorkerProcesses()
 {
 #if ENABLE(SERVICE_WORKER)
-    if (!m_serviceWorkerProcess)
+    if (m_serviceWorkerProcesses.isEmpty())
         return;
 
-#ifndef NDEBUG
-    auto protectedThis = makeRef(*this);
+    while (!m_serviceWorkerProcesses.isEmpty())
+        m_serviceWorkerProcesses.begin()->value->requestTermination(ProcessTerminationReason::RequestedByClient);
 #endif
-    m_serviceWorkerProcess->requestTermination(ProcessTerminationReason::RequestedByClient);
-    ASSERT(!m_processes.contains(m_serviceWorkerProcess));
-    ASSERT(!m_serviceWorkerProcess);
-#endif
 }
 
 void WebProcessPool::syncNetworkProcessCookies()
@@ -1856,20 +1857,28 @@
 #if PLATFORM(IOS)
 #if ENABLE(SERVICE_WORKER)
     auto updateServiceWorkerProcessAssertion = [&] {
-        if (m_serviceWorkerProcess && m_foregroundWebProcessCounter.value()) {
-            if (!m_foregroundTokenForServiceWorkerProcess)
-                m_foregroundTokenForServiceWorkerProcess = m_serviceWorkerProcess->throttler().foregroundActivityToken();
-            m_backgroundTokenForServiceWorkerProcess = nullptr;
+        if (!m_serviceWorkerProcesses.isEmpty() && m_foregroundWebProcessCounter.value()) {
+            // FIXME: We can do better than this once we have process per origin.
+            for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values()) {
+                auto& origin = serviceWorkerProcess->origin();
+                if (!m_foregroundTokensForServiceWorkerProcesses.contains(&origin))
+                    m_foregroundTokensForServiceWorkerProcesses.add(&origin, serviceWorkerProcess->throttler().foregroundActivityToken());
+            }
+            m_backgroundTokensForServiceWorkerProcesses.clear();
             return;
         }
-        if (m_serviceWorkerProcess && m_backgroundWebProcessCounter.value()) {
-            if (!m_backgroundTokenForServiceWorkerProcess)
-                m_backgroundTokenForServiceWorkerProcess = m_serviceWorkerProcess->throttler().backgroundActivityToken();
-            m_foregroundTokenForServiceWorkerProcess = nullptr;
+        if (!m_serviceWorkerProcesses.isEmpty() && m_backgroundWebProcessCounter.value()) {
+            // FIXME: We can do better than this once we have process per origin.
+            for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values()) {
+                auto& origin = serviceWorkerProcess->origin();
+                if (!m_backgroundTokensForServiceWorkerProcesses.contains(&origin))
+                    m_backgroundTokensForServiceWorkerProcesses.add(&origin, serviceWorkerProcess->throttler().backgroundActivityToken());
+            }
+            m_foregroundTokensForServiceWorkerProcesses.clear();
             return;
         }
-        m_foregroundTokenForServiceWorkerProcess = nullptr;
-        m_backgroundTokenForServiceWorkerProcess = nullptr;
+        m_foregroundTokensForServiceWorkerProcesses.clear();
+        m_backgroundTokensForServiceWorkerProcesses.clear();
     };
     updateServiceWorkerProcessAssertion();
 #endif
@@ -1919,4 +1928,16 @@
 #endif
 }
 
+#if ENABLE(SERVICE_WORKER)
+ServiceWorkerProcessProxy* WebProcessPool::serviceWorkerProcessProxyFromPageID(uint64_t pageID) const
+{
+    // FIXME: This is inefficient.
+    for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values()) {
+        if (serviceWorkerProcess->pageID() == pageID)
+            return serviceWorkerProcess;
+    }
+    return nullptr;
+}
+#endif
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.h	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h	2018-03-20 02:31:47 UTC (rev 229735)
@@ -45,6 +45,7 @@
 #include "WebContextClient.h"
 #include "WebContextConnectionClient.h"
 #include "WebProcessProxy.h"
+#include <WebCore/SecurityOriginHash.h>
 #include <WebCore/SharedStringHash.h>
 #include <pal/SessionID.h>
 #include <wtf/Forward.h>
@@ -268,7 +269,7 @@
     void clearCachedCredentials();
     void terminateStorageProcess();
     void terminateNetworkProcess();
-    void terminateServiceWorkerProcess();
+    void terminateServiceWorkerProcesses();
 
     void syncNetworkProcessCookies();
 
@@ -326,12 +327,12 @@
 
     void ensureStorageProcessAndWebsiteDataStore(WebsiteDataStore* relevantDataStore);
     StorageProcessProxy* storageProcess() { return m_storageProcess.get(); }
-    void getStorageProcessConnection(bool isServiceWorkerProcess, PAL::SessionID initialSessionID, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&&);
+    void getStorageProcessConnection(WebProcessProxy&, PAL::SessionID initialSessionID, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&&);
     void storageProcessCrashed(StorageProcessProxy*);
 #if ENABLE(SERVICE_WORKER)
-    void establishWorkerContextConnectionToStorageProcess(StorageProcessProxy&, std::optional<PAL::SessionID>);
-    bool isServiceWorker(uint64_t pageID) const { return m_serviceWorkerProcess && m_serviceWorkerProcess->pageID() == pageID; }
-    ServiceWorkerProcessProxy* serviceWorkerProxy() const { return m_serviceWorkerProcess; }
+    void establishWorkerContextConnectionToStorageProcess(StorageProcessProxy&, WebCore::SecurityOriginData&&, std::optional<PAL::SessionID>);
+    ServiceWorkerProcessProxy* serviceWorkerProcessProxyFromPageID(uint64_t pageID) const;
+    const HashMap<RefPtr<WebCore::SecurityOrigin>, ServiceWorkerProcessProxy*>& serviceWorkerProxies() const { return m_serviceWorkerProcesses; }
     void setAllowsAnySSLCertificateForServiceWorker(bool allows) { m_allowsAnySSLCertificateForServiceWorker = allows; }
     bool allowsAnySSLCertificateForServiceWorker() const { return m_allowsAnySSLCertificateForServiceWorker; }
     void updateServiceWorkerUserAgent(const String& userAgent);
@@ -511,7 +512,7 @@
 
     WebProcessProxy* m_processWithPageCache { nullptr };
 #if ENABLE(SERVICE_WORKER)
-    ServiceWorkerProcessProxy* m_serviceWorkerProcess { nullptr };
+    HashMap<RefPtr<WebCore::SecurityOrigin>, ServiceWorkerProcessProxy*> m_serviceWorkerProcesses;
     bool m_waitingForWorkerContextProcessConnection { false };
     bool m_allowsAnySSLCertificateForServiceWorker { false };
     String m_serviceWorkerUserAgent;
@@ -661,7 +662,7 @@
     Paths m_resolvedPaths;
 
     HashMap<PAL::SessionID, HashSet<WebPageProxy*>> m_sessionToPagesMap;
-    RunLoop::Timer<WebProcessPool> m_serviceWorkerProcessTerminationTimer;
+    RunLoop::Timer<WebProcessPool> m_serviceWorkerProcessesTerminationTimer;
 
 #if PLATFORM(IOS)
     ForegroundWebProcessCounter m_foregroundWebProcessCounter;
@@ -669,8 +670,8 @@
     ProcessThrottler::ForegroundActivityToken m_foregroundTokenForNetworkProcess;
     ProcessThrottler::BackgroundActivityToken m_backgroundTokenForNetworkProcess;
 #if ENABLE(SERVICE_WORKER)
-    ProcessThrottler::ForegroundActivityToken m_foregroundTokenForServiceWorkerProcess;
-    ProcessThrottler::BackgroundActivityToken m_backgroundTokenForServiceWorkerProcess;
+    HashMap<RefPtr<WebCore::SecurityOrigin>, ProcessThrottler::ForegroundActivityToken> m_foregroundTokensForServiceWorkerProcesses;
+    HashMap<RefPtr<WebCore::SecurityOrigin>, ProcessThrottler::BackgroundActivityToken> m_backgroundTokensForServiceWorkerProcesses;
 #endif
 #endif
 };

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (229734 => 229735)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2018-03-20 02:31:47 UTC (rev 229735)
@@ -607,7 +607,7 @@
 
 void WebProcessProxy::getStorageProcessConnection(PAL::SessionID initialSessionID, Ref<Messages::WebProcessProxy::GetStorageProcessConnection::DelayedReply>&& reply)
 {
-    m_processPool->getStorageProcessConnection(isServiceWorkerProcess(), initialSessionID, WTFMove(reply));
+    m_processPool->getStorageProcessConnection(*this, initialSessionID, WTFMove(reply));
 }
 
 #if !PLATFORM(COCOA)

Modified: trunk/Tools/ChangeLog (229734 => 229735)


--- trunk/Tools/ChangeLog	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Tools/ChangeLog	2018-03-20 02:31:47 UTC (rev 229735)
@@ -1,3 +1,15 @@
+2018-03-19  Chris Dumez  <cdu...@apple.com>
+
+        Have one service worker process per security origin
+        https://bugs.webkit.org/show_bug.cgi?id=183600
+        <rdar://problem/35280128>
+
+        Reviewed by Brady Eidson.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+
 2018-03-19  Zalan Bujtas  <za...@apple.com>
 
         [LayoutReloaded] Remove border/padding/contentBox() functions from Layout.Box

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm (229734 => 229735)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2018-03-20 02:30:51 UTC (rev 229734)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2018-03-20 02:31:47 UTC (rev 229735)
@@ -210,7 +210,8 @@
 try {
 
 navigator.serviceWorker.register('/sw.js').then(function(reg) {
-    reg.installing.postMessage("Hello from the web page");
+    worker = reg.installing ? reg.installing : reg.active;
+    worker.postMessage("Hello from the web page");
 }).catch(function(error) {
     log("Registration failed with: " + error);
 });
@@ -1281,4 +1282,64 @@
     done = false;
 }
 
+TEST(ServiceWorkers, ProcessPerOrigin)
+{
+    ASSERT(mainBytes);
+    ASSERT(scriptBytes);
+
+    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
+
+    // Start with a clean slate data store
+    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+    RetainPtr<SWMessageHandler> messageHandler = adoptNS([[SWMessageHandler alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+    RetainPtr<SWSchemes> handler1 = adoptNS([[SWSchemes alloc] init]);
+    handler1->resources.set("sw1://host/main.html", ResourceInfo { @"text/html", mainBytes });
+    handler1->resources.set("sw1://host/sw.js", ResourceInfo { @"application/_javascript_", scriptBytes });
+    [configuration setURLSchemeHandler:handler1.get() forURLScheme:@"sw1"];
+
+    RetainPtr<SWSchemes> handler2 = adoptNS([[SWSchemes alloc] init]);
+    handler2->resources.set("sw2://host/main.html", ResourceInfo { @"text/html", mainBytes });
+    handler2->resources.set("sw2://host/sw.js", ResourceInfo { @"application/_javascript_", scriptBytes });
+    [configuration setURLSchemeHandler:handler2.get() forURLScheme:@"sw2"];
+
+    [configuration.get().processPool _registerURLSchemeServiceWorkersCanHandle:@"sw1"];
+    [configuration.get().processPool _registerURLSchemeServiceWorkersCanHandle:@"sw2"];
+
+    RetainPtr<WKWebView> webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    NSURLRequest *request1 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw1://host/main.html"]];
+    [webView1 loadRequest:request1];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_EQ(1U, webView1.get().configuration.processPool._serviceWorkerProcessCount);
+
+    RetainPtr<WKWebView> webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView2 loadRequest:request1];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_EQ(1U, webView2.get().configuration.processPool._serviceWorkerProcessCount);
+
+    RetainPtr<WKWebView> webView3 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    NSURLRequest *request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw2://host/main.html"]];
+    [webView3 loadRequest:request2];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_EQ(2U, webView3.get().configuration.processPool._serviceWorkerProcessCount);
+}
+
 #endif // WK_API_ENABLED
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to