Need to properly handle removal of worker in SWServer::unregisterServiceWorkerClient...
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jun 2018 20:53:34 +0000 (20:53 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jun 2018 20:53:34 +0000 (20:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186674
<rdar://problem/40974812>

Reviewed by Chris Dumez.

While looping over the running workers map and trying to terminate some of the workers,
there is a chance that the map will be modified synchronously which may affect iterating the map.
This patch removes that potential threat.

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::unregisterServiceWorkerClient):

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

Source/WebCore/ChangeLog
Source/WebCore/workers/service/server/SWServer.cpp

index 3537191..753a342 100644 (file)
@@ -1,3 +1,18 @@
+2018-06-19  Youenn Fablet  <youenn@apple.com>
+
+        Need to properly handle removal of worker in SWServer::unregisterServiceWorkerClient timer lambda
+        https://bugs.webkit.org/show_bug.cgi?id=186674
+        <rdar://problem/40974812>
+
+        Reviewed by Chris Dumez.
+
+        While looping over the running workers map and trying to terminate some of the workers,
+        there is a chance that the map will be modified synchronously which may affect iterating the map.
+        This patch removes that potential threat.
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::unregisterServiceWorkerClient):
+
 2018-06-19  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] Make imported/mozilla/css-animations/test_animation-playstate.html pass reliably
index 0310001..714fd38 100644 (file)
@@ -773,10 +773,14 @@ void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, S
     if (clientIdentifiers.isEmpty()) {
         ASSERT(!iterator->value.terminateServiceWorkersTimer);
         iterator->value.terminateServiceWorkersTimer = std::make_unique<Timer>([clientOrigin, this] {
+            Vector<SWServerWorker*> workersToTerminate;
             for (auto& worker : m_runningOrTerminatingWorkers.values()) {
                 if (worker->isRunning() && worker->origin() == clientOrigin)
-                    terminateWorker(worker);
+                    workersToTerminate.append(worker.ptr());
             }
+            for (auto* worker : workersToTerminate)
+                terminateWorker(*worker);
+
             if (!m_clientsBySecurityOrigin.contains(clientOrigin.clientOrigin)) {
                 if (auto* connection = SWServerToContextConnection::connectionForOrigin(clientOrigin.clientOrigin))
                     connection->connectionMayNoLongerBeNeeded();