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