| <!doctype html> |
| <html> |
| <head> |
| <meta charset=utf-8> |
| <meta name="timeout" content="long"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/common/gc.js"></script> |
| <script src="RTCPeerConnection-helper.js"></script> |
| </head> |
| <body> |
| <script> |
| 'use strict'; |
| |
| // Check that a worker RTCDataChannel is not collected by GC while observing remote pc close |
| |
| const worker = new Worker(`data:text/javascript,(${work.toString()})()`); |
| |
| async function didRemotePcClose(t, closeRemotePc) { |
| let pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection(); |
| t.add_cleanup(async () => await garbageCollect()); |
| pc1.onicecandidate = e => pc2?.addIceCandidate(e?.candidate); |
| pc2.onicecandidate = e => pc1?.addIceCandidate(e?.candidate); |
| let dc1 = pc1.createDataChannel(""); |
| worker.postMessage({channel: dc1}, [dc1]); |
| dc1 = null; |
| const closed = new Promise(r => { |
| worker.onmessage = ({data}) => { |
| if (data == "close") { |
| r(true); |
| } |
| } |
| }); |
| await pc1.setLocalDescription(); |
| await pc2.setRemoteDescription(pc1.localDescription); |
| await pc2.setLocalDescription(); |
| await pc1.setRemoteDescription(pc2.localDescription); |
| if (closeRemotePc) pc2.close(); |
| pc1 = pc2 = null; |
| await garbageCollect(); |
| return await Promise.race([closed, new Promise(r => t.step_timeout(r, 10000))]); |
| } |
| |
| promise_test(async t => { |
| assert_true(await didRemotePcClose(t, true)); |
| }, "Control: detected remote PC being closed using a worker data channel"); |
| |
| promise_test(async t => { |
| assert_false(await didRemotePcClose(t, false)); |
| }, "While remote PC remains open, its worker datachannel should not be collected"); |
| |
| function work() { |
| onmessage = ({data: {channel}}) => { |
| if (channel) { |
| channel.onclose = () => self.postMessage("close"); |
| } |
| }; |
| } |
| </script> |
| </body> |
| </html> |
| |