Title: [295776] trunk
Revision
295776
Author
commit-qu...@webkit.org
Date
2022-06-23 05:43:18 -0700 (Thu, 23 Jun 2022)

Log Message

[ Mac EWS ] imported/w3c/web-platform-tests/workers/semantics/multiple-workers/004.html is a flaky text failure
https://bugs.webkit.org/show_bug.cgi?id=237095
rdar://problem/89367636

Patch by Youenn Fablet <youe...@gmail.com> on 2022-06-23
Reviewed by Chris Dumez.

As per https://html.spec.whatwg.org/multipage/workers.html#concept-WorkerGlobalScope-owner-set,
a WorkerGlobalScope owner set should preserve the insertion order.
imported/w3c/web-platform-tests/workers/semantics/multiple-workers/004.html might be flakky as we sometimes do not run the shared worker synchronously.
In that case, we will send the connect event on the shared worker set.
Before the patch, the shared worker set would not be ordered so it might happen that the first connect event is related to an iframe SharedWorker.
After the patch, we ensure that the first SharedWorker (NetworkProcess being the place where insertion happens) will be the first to trigger the connect event.
This is done by changing the SharedWorker object set from a Map to a ListHashSet.
Covered by added LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering.html

* LayoutTests/http/wpt/service-workers/shared-workers: Added.
* LayoutTests/platform/mac-wk2/TestExpectations:
* Source/WebKit/NetworkProcess/SharedWorker/WebSharedWorker.cpp:
* Source/WebKit/NetworkProcess/SharedWorker/WebSharedWorker.h:

Canonical link: https://commits.webkit.org/251781@main

Modified Paths

Added Paths

Diff

Added: trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering-expected.txt (0 => 295776)


--- trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering-expected.txt	2022-06-23 12:43:18 UTC (rev 295776)
@@ -0,0 +1,3 @@
+
+PASS connect event should fire following SharedWorker creation order
+

Added: trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering-sharedworker.js (0 => 295776)


--- trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering-sharedworker.js	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering-sharedworker.js	2022-06-23 12:43:18 UTC (rev 295776)
@@ -0,0 +1,3 @@
+_onconnect_ = (e) => {
+    e.ports[0].postMessage("got it");
+}

Added: trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering.html (0 => 295776)


--- trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/service-workers/shared-workers/connect-event-ordering.html	2022-06-23 12:43:18 UTC (rev 295776)
@@ -0,0 +1,30 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+if (window.testRunner)
+    testRunner.setUseSeparateServiceWorkerProcess(true);
+
+promise_test(async (test) => {
+    const worker1 = new SharedWorker('connect-event-ordering-sharedworker.js');
+    const worker2 = new SharedWorker('connect-event-ordering-sharedworker.js');
+
+    let result = '';
+    await Promise.all([
+        new Promise(resolve => { worker1.port._onmessage_ = () => {
+            result += 'worker1';
+            resolve();
+        }}),
+        new Promise(resolve => { worker2.port._onmessage_ = () => {
+            result += 'worker2';
+            resolve();
+        }})
+    ]);
+    assert_equals(result, 'worker1worker2');
+}, "connect event should fire following SharedWorker creation order");
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (295775 => 295776)


--- trunk/LayoutTests/platform/mac-wk2/TestExpectations	2022-06-23 12:40:44 UTC (rev 295775)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations	2022-06-23 12:43:18 UTC (rev 295776)
@@ -1618,8 +1618,6 @@
 [ Monterey+ ] accessibility/model-element-attributes.html [ Skip ]
 [ Monterey+ ] model-element/model-element-interactive.html [ Skip ]
 
-webkit.org/b/237095 imported/w3c/web-platform-tests/workers/semantics/multiple-workers/004.html [ Pass Failure ]
-
 webkit.org/b/233621 http/tests/webgpu [ Skip ]
 
 fast/text/install-font-style-recalc.html [ Pass ]

Modified: trunk/Source/WebKit/NetworkProcess/SharedWorker/WebSharedWorker.cpp (295775 => 295776)


--- trunk/Source/WebKit/NetworkProcess/SharedWorker/WebSharedWorker.cpp	2022-06-23 12:40:44 UTC (rev 295775)
+++ trunk/Source/WebKit/NetworkProcess/SharedWorker/WebSharedWorker.cpp	2022-06-23 12:43:18 UTC (rev 295776)
@@ -54,8 +54,8 @@
 WebSharedWorker::~WebSharedWorker()
 {
     if (auto* connection = contextConnection()) {
-        for (auto& sharedWorkerObjectIdentifier : m_sharedWorkerObjects.keys())
-            connection->removeSharedWorkerObject(sharedWorkerObjectIdentifier);
+        for (auto& sharedWorkerObject : m_sharedWorkerObjects)
+            connection->removeSharedWorkerObject(sharedWorkerObject.identifier);
     }
 
     ASSERT(allWorkers().get(m_identifier) == this);
@@ -79,8 +79,8 @@
 
 void WebSharedWorker::didCreateContextConnection(WebSharedWorkerServerToContextConnection& contextConnection)
 {
-    for (auto& sharedWorkerObjectIdentifier : m_sharedWorkerObjects.keys())
-        contextConnection.addSharedWorkerObject(sharedWorkerObjectIdentifier);
+    for (auto& sharedWorkerObject : m_sharedWorkerObjects)
+        contextConnection.addSharedWorkerObject(sharedWorkerObject.identifier);
     if (didFinishFetching())
         launch(contextConnection);
 }
@@ -94,7 +94,8 @@
 
 void WebSharedWorker::addSharedWorkerObject(WebCore::SharedWorkerObjectIdentifier sharedWorkerObjectIdentifier, const WebCore::TransferredMessagePort& port)
 {
-    m_sharedWorkerObjects.add(sharedWorkerObjectIdentifier, SharedWorkerObjectState { false, port });
+    ASSERT(!m_sharedWorkerObjects.contains({ sharedWorkerObjectIdentifier, { false, port } }));
+    m_sharedWorkerObjects.add({ sharedWorkerObjectIdentifier, { false, port } });
     if (auto* connection = contextConnection())
         connection->addSharedWorkerObject(sharedWorkerObjectIdentifier);
 
@@ -103,7 +104,8 @@
 
 void WebSharedWorker::removeSharedWorkerObject(WebCore::SharedWorkerObjectIdentifier sharedWorkerObjectIdentifier)
 {
-    m_sharedWorkerObjects.remove(sharedWorkerObjectIdentifier);
+    ASSERT(m_sharedWorkerObjects.contains({ sharedWorkerObjectIdentifier, { } }));
+    m_sharedWorkerObjects.remove({ sharedWorkerObjectIdentifier, { } });
     if (auto* connection = contextConnection())
         connection->removeSharedWorkerObject(sharedWorkerObjectIdentifier);
 
@@ -112,13 +114,12 @@
 
 void WebSharedWorker::suspend(WebCore::SharedWorkerObjectIdentifier sharedWorkerObjectIdentifier)
 {
-    auto iterator = m_sharedWorkerObjects.find(sharedWorkerObjectIdentifier);
+    auto iterator = m_sharedWorkerObjects.find({ sharedWorkerObjectIdentifier, { } });
     if (iterator == m_sharedWorkerObjects.end())
         return;
 
-    iterator->value.isSuspended = true;
+    iterator->state.isSuspended = true;
     ASSERT(!m_isSuspended);
-
     suspendIfNeeded();
 }
 
@@ -127,8 +128,8 @@
     if (m_isSuspended)
         return;
 
-    for (auto& state : m_sharedWorkerObjects.values()) {
-        if (!state.isSuspended)
+    for (auto& object : m_sharedWorkerObjects) {
+        if (!object.state.isSuspended)
             return;
     }
 
@@ -139,12 +140,11 @@
 
 void WebSharedWorker::resume(WebCore::SharedWorkerObjectIdentifier sharedWorkerObjectIdentifier)
 {
-    auto iterator = m_sharedWorkerObjects.find(sharedWorkerObjectIdentifier);
+    auto iterator = m_sharedWorkerObjects.find({ sharedWorkerObjectIdentifier, { } });
     if (iterator == m_sharedWorkerObjects.end())
         return;
 
-    iterator->value.isSuspended = false;
-
+    iterator->state.isSuspended = false;
     resumeIfNeeded();
 }
 
@@ -160,8 +160,8 @@
 
 void WebSharedWorker::forEachSharedWorkerObject(const Function<void(WebCore::SharedWorkerObjectIdentifier, const WebCore::TransferredMessagePort&)>& apply) const
 {
-    for (auto& [sharedWorkerObjectIdentifier, state] : m_sharedWorkerObjects)
-        apply(sharedWorkerObjectIdentifier, state.port);
+    for (auto& object : m_sharedWorkerObjects)
+        apply(object.identifier, object.state.port);
 }
 
 std::optional<WebCore::ProcessIdentifier> WebSharedWorker::firstSharedWorkerObjectProcess() const
@@ -168,7 +168,7 @@
 {
     if (m_sharedWorkerObjects.isEmpty())
         return std::nullopt;
-    return m_sharedWorkerObjects.begin()->key.processIdentifier();
+    return m_sharedWorkerObjects.first().identifier.processIdentifier();
 }
 
 WebSharedWorkerServerToContextConnection* WebSharedWorker::contextConnection() const

Modified: trunk/Source/WebKit/NetworkProcess/SharedWorker/WebSharedWorker.h (295775 => 295776)


--- trunk/Source/WebKit/NetworkProcess/SharedWorker/WebSharedWorker.h	2022-06-23 12:40:44 UTC (rev 295775)
+++ trunk/Source/WebKit/NetworkProcess/SharedWorker/WebSharedWorker.h	2022-06-23 12:43:18 UTC (rev 295776)
@@ -32,6 +32,7 @@
 #include <WebCore/WorkerFetchResult.h>
 #include <WebCore/WorkerInitializationData.h>
 #include <WebCore/WorkerOptions.h>
+#include <wtf/ListHashSet.h>
 #include <wtf/WeakPtr.h>
 
 namespace WebCore {
@@ -81,6 +82,16 @@
 
     void launch(WebSharedWorkerServerToContextConnection&);
 
+    struct SharedWorkerObjectState {
+        bool isSuspended { false };
+        WebCore::TransferredMessagePort port;
+    };
+
+    struct Object {
+        WebCore::SharedWorkerObjectIdentifier identifier;
+        SharedWorkerObjectState state;
+    };
+
 private:
     WebSharedWorker(WebSharedWorker&&) = delete;
     WebSharedWorker& operator=(WebSharedWorker&&) = delete;
@@ -90,16 +101,11 @@
     void suspendIfNeeded();
     void resumeIfNeeded();
 
-    struct SharedWorkerObjectState {
-        bool isSuspended { false };
-        WebCore::TransferredMessagePort port;
-    };
-
     WebSharedWorkerServer& m_server;
     WebCore::SharedWorkerIdentifier m_identifier;
     WebCore::SharedWorkerKey m_key;
     WebCore::WorkerOptions m_workerOptions;
-    HashMap<WebCore::SharedWorkerObjectIdentifier, SharedWorkerObjectState> m_sharedWorkerObjects;
+    ListHashSet<Object> m_sharedWorkerObjects;
     WebCore::WorkerFetchResult m_fetchResult;
     WebCore::WorkerInitializationData m_initializationData;
     bool m_isRunning { false };
@@ -107,3 +113,16 @@
 };
 
 } // namespace WebKit
+
+namespace WTF {
+
+struct WebSharedWorkerObjectHash {
+    static unsigned hash(const WebKit::WebSharedWorker::Object& object) { return DefaultHash<WebCore::SharedWorkerObjectIdentifier>::hash(object.identifier); }
+    static bool equal(const WebKit::WebSharedWorker::Object& a, const WebKit::WebSharedWorker::Object& b) { return a.identifier == b.identifier; }
+    static constexpr bool safeToCompareToEmptyOrDeleted = true;
+};
+
+template<> struct HashTraits<WebKit::WebSharedWorker::Object> : SimpleClassHashTraits<WebSharedWorkerObjectHash> { };
+template<> struct DefaultHash<WebKit::WebSharedWorker::Object> : WebSharedWorkerObjectHash { };
+
+} // namespace WTF
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to