haikuwebkit/LayoutTests/fast/events/message-port-postMessage-re...

51 lines
1.1 KiB
HTML
Raw Permalink Normal View History

Recursive MessagePort.postMessage() calls causes tab to become unresponsive https://bugs.webkit.org/show_bug.cgi?id=168548 <rdar://problem/29808005> Reviewed by Darin Adler. Source/WebCore: MessagePort::dispatchMessages() was getting messages one by one of the channel's MessageQueue and firing the MessageEvent for each of them. The issue is that we can get stuck in an infinite loop if the MessageEvent handler posts a message on the same post. To address the issue, we now takes all messages from the queue before iterating over them to fire the event. This way, if new messages are added to the queue in one of the MessageEvent handlers, they will not be processed until the next event loop iteration, as is expected. Test: fast/events/message-port-postMessage-recursive.html * dom/MessagePort.cpp: (WebCore::MessagePort::dispatchMessages): * dom/MessagePortChannel.h: (WebCore::MessagePortChannel::EventData::EventData): * dom/default/PlatformMessagePortChannel.cpp: (WebCore::MessagePortChannel::postMessageToRemote): * dom/default/PlatformMessagePortChannel.h: (WebCore::PlatformMessagePortChannel::MessagePortQueue::takeMessage): (WebCore::PlatformMessagePortChannel::MessagePortQueue::takeAllMessages): (WebCore::PlatformMessagePortChannel::MessagePortQueue::appendAndCheckEmpty): Source/WTF: Add API to retrieve all messages in the queue at once. * wtf/MessageQueue.h: LayoutTests: Add layout test coverage. The test used to time out, it now passes. The test also passes on Firefox and Chrome. * fast/events/message-port-postMessage-recursive-expected.txt: Added. * fast/events/message-port-postMessage-recursive.html: Added. Canonical link: https://commits.webkit.org/185570@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@212609 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-02-18 23:58:57 +00:00
<!DOCTYPE html>
<html>
<body>
<script src="../../resources/js-test-pre.js"></script>
<script>
description("Tests that recursive calls to MessagePort.postMessage() do not preempt timers.");
jsTestIsAsync = true;
function simulateSetImmediate()
{
var channel = new MessageChannel();
// Use a fifo linked list to call callbacks in the right order.
var head = {};
var tail = head;
channel['port1'].onmessage = function() {
if (head.next != null) {
head = head.next;
var cb = head.cb;
head.cb = null;
cb();
}
};
return function(cb) {
tail.next = {cb: cb};
tail = tail.next;
channel['port2'].postMessage(0);
};
}
window.setImmediate = simulateSetImmediate();
var shouldExit = false;
function iterate() {
if (shouldExit) {
testPassed("Timer has fired.");
finishJSTest();
return;
}
setImmediate(iterate);
}
setImmediate(iterate);
setTimeout(function() {
shouldExit = true;
}, 10);
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>