Title: [225486] trunk/Source/WebCore
Revision
225486
Author
commit-qu...@webkit.org
Date
2017-12-04 12:35:05 -0800 (Mon, 04 Dec 2017)

Log Message

Call "Terminate Service Worker" on all workers when all their clients are gone
https://bugs.webkit.org/show_bug.cgi?id=179552

Patch by Youenn Fablet <you...@apple.com> on 2017-12-04
Reviewed by Chris Dumez.

Tested manually.

When SWServer detects that there is no longer any client for a given client origin,
it iterates through the running workers to terminate them if they have the given client origin.
A timer of 60 seconds is used in case a user closes a tab or a window, and reopens one with the same origin shortly after.

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::findClientByIdentifier):
(WebCore::SWServer::matchAll):
(WebCore::SWServer::registerServiceWorkerClient):
(WebCore::SWServer::unregisterServiceWorkerClient):
* workers/service/server/SWServer.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (225485 => 225486)


--- trunk/Source/WebCore/ChangeLog	2017-12-04 20:31:35 UTC (rev 225485)
+++ trunk/Source/WebCore/ChangeLog	2017-12-04 20:35:05 UTC (rev 225486)
@@ -1,3 +1,23 @@
+2017-12-04  Youenn Fablet  <you...@apple.com>
+
+        Call "Terminate Service Worker" on all workers when all their clients are gone
+        https://bugs.webkit.org/show_bug.cgi?id=179552
+
+        Reviewed by Chris Dumez.
+
+        Tested manually.
+
+        When SWServer detects that there is no longer any client for a given client origin,
+        it iterates through the running workers to terminate them if they have the given client origin.
+        A timer of 60 seconds is used in case a user closes a tab or a window, and reopens one with the same origin shortly after.
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::findClientByIdentifier):
+        (WebCore::SWServer::matchAll):
+        (WebCore::SWServer::registerServiceWorkerClient):
+        (WebCore::SWServer::unregisterServiceWorkerClient):
+        * workers/service/server/SWServer.h:
+
 2017-12-04  Antti Koivisto  <an...@apple.com>
 
         Enable selector filtering for ::before and ::after pseudo element resolution

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


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2017-12-04 20:31:35 UTC (rev 225485)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2017-12-04 20:35:05 UTC (rev 225486)
@@ -52,6 +52,8 @@
     return generateObjectIdentifier<ServiceWorkerIdentifierType>();
 }
 
+static Seconds terminationDelay { 60_s };
+
 SWServer::Connection::Connection(SWServer& server)
     : m_server(server)
     , m_identifier(generateObjectIdentifier<SWServerConnectionIdentifierType>())
@@ -322,7 +324,7 @@
     if (iterator == m_clients.end())
         return std::nullopt;
 
-    auto& clients = iterator->value;
+    auto& clients = iterator->value.clients;
     auto position = clients.findMatching([&] (const auto& client) {
         return clientIdentifier == client.identifier;
     });
@@ -336,7 +338,7 @@
     // FIXME: Support reserved client filtering.
     // FIXME: Support WindowClient additional properties.
 
-    auto clients = m_clients.get(worker.origin());
+    auto clients = m_clients.find(worker.origin())->value.clients;
 
     if (!options.includeUncontrolled) {
         clients.removeAllMatching([&] (const auto& client) {
@@ -615,9 +617,13 @@
 
 void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceWorkerClientIdentifier identifier, ServiceWorkerClientData&& data)
 {
-    m_clients.ensure(WTFMove(clientOrigin), [] {
-        return Vector<ServiceWorkerClientInformation> { };
-    }).iterator->value.append(ServiceWorkerClientInformation { identifier, WTFMove(data) });
+    auto& clientsData = m_clients.ensure(WTFMove(clientOrigin), [] {
+        return Clients { };
+    }).iterator->value;
+
+    clientsData.clients.append(ServiceWorkerClientInformation { identifier, WTFMove(data) });
+    if (clientsData.terminateServiceWorkersTimer)
+        clientsData.terminateServiceWorkersTimer = nullptr;
 }
 
 void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, ServiceWorkerClientIdentifier identifier)
@@ -625,14 +631,23 @@
     auto iterator = m_clients.find(clientOrigin);
     ASSERT(iterator != m_clients.end());
 
-    auto& clients = iterator->value;
+    auto& clients = iterator->value.clients;
     clients.removeFirstMatching([&] (const auto& item) {
         return identifier == item.identifier;
     });
-    if (clients.isEmpty()) {
-        // FIXME: We might want to terminate any clientOrigin related service worker.
-        m_clients.remove(iterator);
-    }
+
+    if (!clients.isEmpty() || m_runningOrTerminatingWorkers.isEmpty())
+        return;
+
+    ASSERT(!iterator->value.terminateServiceWorkersTimer);
+    iterator->value.terminateServiceWorkersTimer = std::make_unique<Timer>([clientOrigin, this] {
+        for (auto& worker : m_runningOrTerminatingWorkers.values()) {
+            if (worker->origin() == clientOrigin)
+                terminateWorker(worker);
+        }
+        m_clients.remove(clientOrigin);
+    });
+    iterator->value.terminateServiceWorkersTimer->startOneShot(terminationDelay);
 }
 
 } // namespace WebCore

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


--- trunk/Source/WebCore/workers/service/server/SWServer.h	2017-12-04 20:31:35 UTC (rev 225485)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h	2017-12-04 20:35:05 UTC (rev 225486)
@@ -59,6 +59,7 @@
 struct ServiceWorkerContextData;
 struct ServiceWorkerFetchResult;
 struct ServiceWorkerRegistrationData;
+class Timer;
 
 class SWServer {
     WTF_MAKE_FAST_ALLOCATED;
@@ -184,7 +185,11 @@
 
     HashMap<ServiceWorkerIdentifier, Ref<SWServerWorker>> m_runningOrTerminatingWorkers;
 
-    HashMap<ClientOrigin, Vector<ServiceWorkerClientInformation>> m_clients;
+    struct Clients {
+        Vector<ServiceWorkerClientInformation> clients;
+        std::unique_ptr<Timer> terminateServiceWorkersTimer;
+    };
+    HashMap<ClientOrigin, Clients> m_clients;
     HashMap<ServiceWorkerClientIdentifier, ServiceWorkerIdentifier> m_clientToControllingWorker;
 
     RefPtr<Thread> m_taskThread;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to