<html>
<head>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../resources/gc.js"></script>
</head>
<body>
<script>
promise_test(async t => {
// Some scheduled events can hold Persistent references to RTCPeerConnection.
// See |RTCPeerConnection::ChangeIceGatheringState()| or
// |RTCPeerConnection::ChangePeerConnectionState()| for example.
// This test checks that such undelivered events don't prevent their parent
// RTCPeerConnection object from garbage collection after destroying
// corresponding execution context.
let iframe = document.createElement("iframe");
document.body.appendChild(iframe);
let iframe_pc = new iframe.contentWindow.RTCPeerConnection();
assert_equals(iframe_pc.signalingState, 'stable');
iframe_pc.createDataChannel('foo');
let frameRemoved = new Promise(function(resolve, reject) {
// Destroy frame (and |iframe_pc| related execution context) just before
// delivering scheduled "icegatheringstatechange" event.
internals.waitForPeerConnectionDispatchEventsTaskCreated(iframe_pc)
.then(() => { iframe.remove(); resolve(); });
iframe_pc.createOffer()
.then((offer) => iframe_pc.setLocalDescription(offer));
});
await frameRemoved;
assert_equals(iframe_pc.signalingState, 'closed');
assert_equals(internals.peerConnectionCount(), 1);
iframe_pc = null;
await asyncGC();
assert_equals(internals.peerConnectionCount(), 0);
}, 'PeerConnection with undelivered events is closed and garbage collected');
</script>
</body>
</html>