Title: [227359] branches/safari-605-branch

Diff

Modified: branches/safari-605-branch/LayoutTests/ChangeLog (227358 => 227359)


--- branches/safari-605-branch/LayoutTests/ChangeLog	2018-01-22 22:15:22 UTC (rev 227358)
+++ branches/safari-605-branch/LayoutTests/ChangeLog	2018-01-22 22:17:09 UTC (rev 227359)
@@ -1,5 +1,24 @@
 2018-01-22  Jason Marcell  <[email protected]>
 
+        Cherry-pick r227174. rdar://problem/36723030
+
+    2018-01-18  Chris Dumez  <[email protected]>
+
+            We should be able to terminate service workers that are unresponsive
+            https://bugs.webkit.org/show_bug.cgi?id=181563
+            <rdar://problem/35280031>
+
+            Reviewed by Alex Christensen.
+
+            Add layout test coverage.
+
+            * http/tests/workers/service/postmessage-after-terminating-hung-worker-expected.txt: Added.
+            * http/tests/workers/service/postmessage-after-terminating-hung-worker.html: Added.
+            * http/tests/workers/service/resources/postmessage-after-terminating-hung-worker.js: Added.
+            * http/tests/workers/service/resources/postmessage-echo-worker-mayhang.js: Added.
+
+2018-01-22  Jason Marcell  <[email protected]>
+
         Cherry-pick r227280. rdar://problem/36722450
 
     2018-01-19  Ryosuke Niwa  <[email protected]>

Added: branches/safari-605-branch/LayoutTests/http/tests/workers/service/postmessage-after-terminating-hung-worker-expected.txt (0 => 227359)


--- branches/safari-605-branch/LayoutTests/http/tests/workers/service/postmessage-after-terminating-hung-worker-expected.txt	                        (rev 0)
+++ branches/safari-605-branch/LayoutTests/http/tests/workers/service/postmessage-after-terminating-hung-worker-expected.txt	2018-01-22 22:17:09 UTC (rev 227359)
@@ -0,0 +1,8 @@
+PASS: Service worker received message 'HANG'
+PASS: ServiceWorker received message: PASS: Service worker received message 'HANG'
+Service Worker should now be hung
+Terminating service worker...
+Terminated service worker.
+PASS: Service worker received message 'MessageAfterTerminatingHungServiceWorker'
+PASS: Service worker responded to message after hanging and being terminated
+

Added: branches/safari-605-branch/LayoutTests/http/tests/workers/service/postmessage-after-terminating-hung-worker.html (0 => 227359)


--- branches/safari-605-branch/LayoutTests/http/tests/workers/service/postmessage-after-terminating-hung-worker.html	                        (rev 0)
+++ branches/safari-605-branch/LayoutTests/http/tests/workers/service/postmessage-after-terminating-hung-worker.html	2018-01-22 22:17:09 UTC (rev 227359)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+
+<script src=""
+</body>
+</html>

Added: branches/safari-605-branch/LayoutTests/http/tests/workers/service/resources/postmessage-after-terminating-hung-worker.js (0 => 227359)


--- branches/safari-605-branch/LayoutTests/http/tests/workers/service/resources/postmessage-after-terminating-hung-worker.js	                        (rev 0)
+++ branches/safari-605-branch/LayoutTests/http/tests/workers/service/resources/postmessage-after-terminating-hung-worker.js	2018-01-22 22:17:09 UTC (rev 227359)
@@ -0,0 +1,29 @@
+let state = "WaitingForHang";
+
+navigator.serviceWorker.addEventListener("message", function(event) {
+    log(event.data);
+    if (state === "WaitingForHang") {
+        log("PASS: ServiceWorker received message: " + event.data);
+        log("Service Worker should now be hung");
+        log("Terminating service worker...")
+        internals.terminateServiceWorker(worker);
+        log("Terminated service worker.");
+        state = "WaitingForMessageAfterTerminatingHungServiceWorker"
+        handle = setInterval(function() {
+            worker.postMessage("MessageAfterTerminatingHungServiceWorker");
+        }, 10);
+        return;
+    }
+    if (state === "WaitingForMessageAfterTerminatingHungServiceWorker") {
+        log("PASS: Service worker responded to message after hanging and being terminated");
+        state = "Done";
+        clearInterval(handle);
+        finishSWTest();
+        return;
+    }
+});
+
+navigator.serviceWorker.register("resources/postmessage-echo-worker-mayhang.js", { }).then(function(registration) {
+    worker = registration.installing;
+    worker.postMessage("HANG");
+});

Added: branches/safari-605-branch/LayoutTests/http/tests/workers/service/resources/postmessage-echo-worker-mayhang.js (0 => 227359)


--- branches/safari-605-branch/LayoutTests/http/tests/workers/service/resources/postmessage-echo-worker-mayhang.js	                        (rev 0)
+++ branches/safari-605-branch/LayoutTests/http/tests/workers/service/resources/postmessage-echo-worker-mayhang.js	2018-01-22 22:17:09 UTC (rev 227359)
@@ -0,0 +1,8 @@
+self.addEventListener("message", (event) => {
+    event.source.postMessage("PASS: Service worker received message '" + event.data + "'");
+
+    if (event.data ="" "HANG") {
+        while(1) { };
+    }
+});
+

Modified: branches/safari-605-branch/Source/WTF/ChangeLog (227358 => 227359)


--- branches/safari-605-branch/Source/WTF/ChangeLog	2018-01-22 22:15:22 UTC (rev 227358)
+++ branches/safari-605-branch/Source/WTF/ChangeLog	2018-01-22 22:17:09 UTC (rev 227359)
@@ -1,3 +1,19 @@
+2018-01-22  Jason Marcell  <[email protected]>
+
+        Cherry-pick r227174. rdar://problem/36723030
+
+    2018-01-18  Chris Dumez  <[email protected]>
+
+            We should be able to terminate service workers that are unresponsive
+            https://bugs.webkit.org/show_bug.cgi?id=181563
+            <rdar://problem/35280031>
+
+            Reviewed by Alex Christensen.
+
+            * wtf/ObjectIdentifier.h:
+            (WTF::ObjectIdentifier::loggingString const):
+            Allow using loggingString() from RELEASE_LOG().
+
 2018-01-18  Jason Marcell  <[email protected]>
 
         Cherry-pick r226956. rdar://problem/36598688

Modified: branches/safari-605-branch/Source/WTF/wtf/ObjectIdentifier.h (227358 => 227359)


--- branches/safari-605-branch/Source/WTF/wtf/ObjectIdentifier.h	2018-01-22 22:15:22 UTC (rev 227358)
+++ branches/safari-605-branch/Source/WTF/wtf/ObjectIdentifier.h	2018-01-22 22:17:09 UTC (rev 227359)
@@ -67,12 +67,10 @@
 
     uint64_t toUInt64() const { return m_identifier; }
     
-#ifndef NDEBUG
     String loggingString() const
     {
         return String::number(m_identifier);
     }
-#endif
 
 private:
     template<typename U> friend ObjectIdentifier<U> generateObjectIdentifier();

Modified: branches/safari-605-branch/Source/WebCore/ChangeLog (227358 => 227359)


--- branches/safari-605-branch/Source/WebCore/ChangeLog	2018-01-22 22:15:22 UTC (rev 227358)
+++ branches/safari-605-branch/Source/WebCore/ChangeLog	2018-01-22 22:17:09 UTC (rev 227359)
@@ -1,5 +1,33 @@
 2018-01-22  Jason Marcell  <[email protected]>
 
+        Cherry-pick r227174. rdar://problem/36723030
+
+    2018-01-18  Chris Dumez  <[email protected]>
+
+            We should be able to terminate service workers that are unresponsive
+            https://bugs.webkit.org/show_bug.cgi?id=181563
+            <rdar://problem/35280031>
+
+            Reviewed by Alex Christensen.
+
+            Test: http/tests/workers/service/postmessage-after-terminating-hung-worker.html
+
+            * workers/service/context/SWContextManager.cpp:
+            (WebCore::SWContextManager::terminateWorker):
+            Before calling WorkerThread::stop(), set a timer with the given timeout parameter.
+            If the worker thread has not stopped when the timer fires, forcefully exit the
+            service worker process. The StorageProcess will take care of relaunching the
+            service worker process if it exits abruptly.
+
+            (WebCore::SWContextManager::serviceWorkerFailedToTerminate):
+            Log error message if we failed to terminate a service worker and call exit().
+
+            (WebCore::SWContextManager::ServiceWorkerTerminationRequest::ServiceWorkerTerminationRequest):
+
+            * workers/service/context/SWContextManager.h:
+
+2018-01-22  Jason Marcell  <[email protected]>
+
         Cherry-pick r227280. rdar://problem/36722450
 
     2018-01-19  Ryosuke Niwa  <[email protected]>

Modified: branches/safari-605-branch/Source/WebCore/workers/service/context/SWContextManager.cpp (227358 => 227359)


--- branches/safari-605-branch/Source/WebCore/workers/service/context/SWContextManager.cpp	2018-01-22 22:15:22 UTC (rev 227358)
+++ branches/safari-605-branch/Source/WebCore/workers/service/context/SWContextManager.cpp	2018-01-22 22:17:09 UTC (rev 227359)
@@ -27,8 +27,11 @@
 
 #if ENABLE(SERVICE_WORKER)
 #include "SWContextManager.h"
+
+#include "Logging.h"
 #include "ServiceWorkerClientIdentifier.h"
 #include "ServiceWorkerGlobalScope.h"
+#include <unistd.h>
 
 namespace WebCore {
 
@@ -102,21 +105,28 @@
     serviceWorker->thread().fireActivateEvent();
 }
 
-void SWContextManager::terminateWorker(ServiceWorkerIdentifier identifier, Function<void()>&& completionHandler)
+void SWContextManager::terminateWorker(ServiceWorkerIdentifier identifier, Seconds timeout, Function<void()>&& completionHandler)
 {
     auto serviceWorker = m_workerMap.take(identifier);
-    if (!serviceWorker)
+    if (!serviceWorker) {
+        if (completionHandler)
+            completionHandler();
         return;
+    }
 
     serviceWorker->setAsTerminatingOrTerminated();
 
-    serviceWorker->thread().stop([identifier, serviceWorker = WTFMove(serviceWorker), completionHandler = WTFMove(completionHandler)]() mutable {
+    m_pendingServiceWorkerTerminationRequests.add(identifier, std::make_unique<ServiceWorkerTerminationRequest>(*this, identifier, timeout));
+
+    serviceWorker->thread().stop([this, identifier, serviceWorker = WTFMove(serviceWorker), completionHandler = WTFMove(completionHandler)]() mutable {
+        m_pendingServiceWorkerTerminationRequests.remove(identifier);
+
         if (auto* connection = SWContextManager::singleton().connection())
             connection->workerTerminated(identifier);
 
         if (completionHandler)
             completionHandler();
-        
+
         // Spin the runloop before releasing the worker thread proxy, as there would otherwise be
         // a race towards its destruction.
         callOnMainThread([serviceWorker = WTFMove(serviceWorker)] { });
@@ -141,6 +151,19 @@
     return true;
 }
 
+NO_RETURN_DUE_TO_CRASH void SWContextManager::serviceWorkerFailedToTerminate(ServiceWorkerIdentifier serviceWorkerIdentifier)
+{
+    UNUSED_PARAM(serviceWorkerIdentifier);
+    RELEASE_LOG_ERROR(ServiceWorker, "Failed to terminate service worker with identifier %s, killing the service worker process", serviceWorkerIdentifier.loggingString().utf8().data());
+    _exit(EXIT_FAILURE);
+}
+
+SWContextManager::ServiceWorkerTerminationRequest::ServiceWorkerTerminationRequest(SWContextManager& manager, ServiceWorkerIdentifier serviceWorkerIdentifier, Seconds timeout)
+    : m_timeoutTimer([this, &manager, serviceWorkerIdentifier] { manager.serviceWorkerFailedToTerminate(serviceWorkerIdentifier); })
+{
+    m_timeoutTimer.startOneShot(timeout);
+}
+
 } // namespace WebCore
 
 #endif

Modified: branches/safari-605-branch/Source/WebCore/workers/service/context/SWContextManager.h (227358 => 227359)


--- branches/safari-605-branch/Source/WebCore/workers/service/context/SWContextManager.h	2018-01-22 22:15:22 UTC (rev 227358)
+++ branches/safari-605-branch/Source/WebCore/workers/service/context/SWContextManager.h	2018-01-22 22:17:09 UTC (rev 227359)
@@ -70,7 +70,7 @@
     WEBCORE_EXPORT void postMessageToServiceWorker(ServiceWorkerIdentifier destination, Ref<SerializedScriptValue>&& message, ServiceWorkerOrClientData&& sourceData);
     WEBCORE_EXPORT void fireInstallEvent(ServiceWorkerIdentifier);
     WEBCORE_EXPORT void fireActivateEvent(ServiceWorkerIdentifier);
-    WEBCORE_EXPORT void terminateWorker(ServiceWorkerIdentifier, Function<void()>&&);
+    WEBCORE_EXPORT void terminateWorker(ServiceWorkerIdentifier, Seconds timeout, Function<void()>&&);
 
     void forEachServiceWorkerThread(const WTF::Function<void(ServiceWorkerThreadProxy&)>&);
 
@@ -85,10 +85,20 @@
     SWContextManager() = default;
 
     void startedServiceWorker(std::optional<ServiceWorkerJobDataIdentifier>, ServiceWorkerIdentifier, const String& exceptionMessage);
+    void serviceWorkerFailedToTerminate(ServiceWorkerIdentifier);
 
     HashMap<ServiceWorkerIdentifier, RefPtr<ServiceWorkerThreadProxy>> m_workerMap;
     std::unique_ptr<Connection> m_connection;
     ServiceWorkerCreationCallback* m_serviceWorkerCreationCallback { nullptr };
+
+    class ServiceWorkerTerminationRequest {
+    public:
+        ServiceWorkerTerminationRequest(SWContextManager&, ServiceWorkerIdentifier, Seconds timeout);
+
+    private:
+        Timer m_timeoutTimer;
+    };
+    HashMap<ServiceWorkerIdentifier, std::unique_ptr<ServiceWorkerTerminationRequest>> m_pendingServiceWorkerTerminationRequests;
 };
 
 } // namespace WebCore

Modified: branches/safari-605-branch/Source/WebKit/ChangeLog (227358 => 227359)


--- branches/safari-605-branch/Source/WebKit/ChangeLog	2018-01-22 22:15:22 UTC (rev 227358)
+++ branches/safari-605-branch/Source/WebKit/ChangeLog	2018-01-22 22:17:09 UTC (rev 227359)
@@ -1,5 +1,27 @@
 2018-01-22  Jason Marcell  <[email protected]>
 
+        Cherry-pick r227174. rdar://problem/36723030
+
+    2018-01-18  Chris Dumez  <[email protected]>
+
+            We should be able to terminate service workers that are unresponsive
+            https://bugs.webkit.org/show_bug.cgi?id=181563
+            <rdar://problem/35280031>
+
+            Reviewed by Alex Christensen.
+
+            * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+            (WebKit::WebSWContextManagerConnection::terminateWorker):
+            Use a 10 second timeout for forcefully exiting the service worker process when
+            the service worker in question fails to terminate.
+
+            (WebKit::WebSWContextManagerConnection::syncTerminateWorker):
+            Use a 100ms timeout for forcefully exiting the service worker process when
+            the service worker in question fails to terminate. This method is only called
+            from the layout tests, which is why we use a very short timeout.
+
+2018-01-22  Jason Marcell  <[email protected]>
+
         Cherry-pick r227274. rdar://problem/36722660
 
     2018-01-20  Andy Estes  <[email protected]>

Modified: branches/safari-605-branch/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (227358 => 227359)


--- branches/safari-605-branch/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2018-01-22 22:15:22 UTC (rev 227358)
+++ branches/safari-605-branch/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2018-01-22 22:17:09 UTC (rev 227359)
@@ -62,6 +62,9 @@
 
 namespace WebKit {
 
+static const Seconds asyncWorkerTerminationTimeout { 10_s };
+static const Seconds syncWorkerTerminationTimeout { 100_ms }; // Only used by layout tests.
+
 class ServiceWorkerFrameLoaderClient final : public EmptyFrameLoaderClient {
 public:
     ServiceWorkerFrameLoaderClient(WebSWContextManagerConnection& connection, PAL::SessionID sessionID, uint64_t pageID, uint64_t frameID, const String& userAgent)
@@ -196,12 +199,12 @@
 
 void WebSWContextManagerConnection::terminateWorker(ServiceWorkerIdentifier identifier)
 {
-    SWContextManager::singleton().terminateWorker(identifier, nullptr);
+    SWContextManager::singleton().terminateWorker(identifier, asyncWorkerTerminationTimeout, nullptr);
 }
 
 void WebSWContextManagerConnection::syncTerminateWorker(ServiceWorkerIdentifier identifier, Ref<Messages::WebSWContextManagerConnection::SyncTerminateWorker::DelayedReply>&& reply)
 {
-    SWContextManager::singleton().terminateWorker(identifier, [reply = WTFMove(reply)] {
+    SWContextManager::singleton().terminateWorker(identifier, syncWorkerTerminationTimeout, [reply = WTFMove(reply)] {
         reply->send();
     });
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to