mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
MessagePort: implement disentanglement (#36654)
Implement [disentangle](https://html.spec.whatwg.org/multipage/#disentangle) Remove bespoke gc logic which now becomes unnecessary. Adds a wpt test that hits the "disentangle while in transfer" logic. Updates streams code, fixing an error where disentanglement is conditional on an error. Test coverage: there are existing tests in `/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js` for the no transfer case, and the simple completed transfer case, and this PR adds a test for the more complicated transfer in progress case. Fix https://github.com/servo/servo/issues/36465 --------- Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
This commit is contained in:
parent
c46402e222
commit
af5d665efa
19 changed files with 356 additions and 191 deletions
4
tests/wpt/meta/MANIFEST.json
vendored
4
tests/wpt/meta/MANIFEST.json
vendored
|
@ -518802,7 +518802,7 @@
|
|||
"close-event": {
|
||||
"resources": {
|
||||
"helper.js": [
|
||||
"cb9ea9fe981e95374b836255c752a42de788fc7b",
|
||||
"48744ac1c5b530ef8d46c3d9a0378c698353a5bc",
|
||||
[]
|
||||
]
|
||||
}
|
||||
|
@ -848537,7 +848537,7 @@
|
|||
]
|
||||
],
|
||||
"explicitly-closed.tentative.window.js": [
|
||||
"612003d58eaea908ad93294a7bbf777184356a28",
|
||||
"12bfa0bd73e9278e39b825d4fa81437f943cbd02",
|
||||
[
|
||||
"webmessaging/message-channels/close-event/explicitly-closed.tentative.window.html",
|
||||
{
|
||||
|
|
|
@ -95,9 +95,6 @@
|
|||
[History interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[MessagePort interface: attribute onclose]
|
||||
expected: FAIL
|
||||
|
||||
[WorkerGlobalScope interface: attribute onlanguagechange]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1517,9 +1517,6 @@
|
|||
[SVGSVGElement interface: attribute onpagereveal]
|
||||
expected: FAIL
|
||||
|
||||
[MessagePort interface: attribute onclose]
|
||||
expected: FAIL
|
||||
|
||||
[NotRestoredReasonDetails interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -5363,9 +5360,6 @@
|
|||
[Navigator interface: window.navigator must inherit property "pdfViewerEnabled" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[MessagePort interface: attribute onclose]
|
||||
expected: FAIL
|
||||
|
||||
[SharedWorker interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[explicitly-closed.tentative.window.html]
|
||||
expected: TIMEOUT
|
||||
[Close event on port2 is fired when port1 is explicitly closed]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Close event on port2 is fired when port1, which is in a different window, is explicitly closed.]
|
||||
expected: TIMEOUT
|
|
@ -33,3 +33,13 @@ promise_test(async t => {
|
|||
});
|
||||
await closeEventPromise;
|
||||
}, 'Close event on port2 is fired when port1, which is in a different window, is explicitly closed.')
|
||||
|
||||
promise_test(async t => {
|
||||
const rc = await addWindow();
|
||||
const waitForPort = expectMessagePortFromWindowWithoutStartingIt(window);
|
||||
await createMessageChannelAndSendPortFollowedByClose(rc);
|
||||
const port = await waitForPort;
|
||||
const closeEventPromise = createCloseEventPromise(port);
|
||||
port.start();
|
||||
await closeEventPromise;
|
||||
}, 'Close event on port2 is fired when port1, in a different window, is closed during the transfer of port2.')
|
||||
|
|
|
@ -21,6 +21,44 @@ function expectMessagePortFromWindow(window) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new promise that resolves when the window receives
|
||||
* the MessagePort and does not start it.
|
||||
*
|
||||
* @param {Window} window - The window to wait for the MessagePort.
|
||||
* @returns {Promise<MessagePort>} A promise you should await to ensure the
|
||||
* window
|
||||
* receives the MessagePort.
|
||||
*/
|
||||
function expectMessagePortFromWindowWithoutStartingIt(window) {
|
||||
return new Promise(resolve => {
|
||||
window.onmessage = e => {
|
||||
try {
|
||||
assert_true(e.ports[0] instanceof window.MessagePort);
|
||||
resolve(e.ports[0]);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MessageChannel and transfers one of the ports to
|
||||
* the window which opened the window with a remote context provided
|
||||
* as an argument, and immediately closes the entangled port.
|
||||
*
|
||||
* @param {RemoteContextWrapper} remoteContextWrapper
|
||||
*/
|
||||
async function createMessageChannelAndSendPortFollowedByClose(remoteContextWrapper) {
|
||||
await remoteContextWrapper.executeScript(() => {
|
||||
const {port1, port2} = new MessageChannel();
|
||||
port1.start();
|
||||
window.opener.postMessage({}, '*', [port2]);
|
||||
port1.close();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MessageChannel and transfers one of the ports to
|
||||
* the window which opened the window with a remote context provided
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue