[whatwg] MessagePort close event and discarding a Document

Currently, HTML5 specifies that when a Document is discarded, "close" event
should be asynchronously dispatched to MessagePorts that are entangled with
ports belonging (in some specific sense) to this document.

There is a race with garbage collection inherent to this requirement. Below
I describe the issue in detail, and propose a solution.

Suppose we have two browsing contexts, frameA and frameB, and two
MessagePorts, portA and portB, owned by these contexts respectively. The
ports are entangled with each other, and their queues are started.

Further, portA is not reachable from live code, but has a "close" event
listener (set via either onclose or addEventListener). Port portB is also
unreachable, so garbage collection can destroy both ports.

Now, we close frameB. This results in its document being discarded, so a
"close" event is dispatched on portA (portA becomes GC protected when the
task to dispatch it is posted). However, no event is dispatched if portA and
portB are collected before the document is destroyed. The problem is that
observable behavior depends on GC order, which it shouldn't.

In practice, it is normally the same GC pass that destroys the Document and
both unreachable ports, so a straightforward implementation is likely to
crash due to using semi-deleted objects.

I propose to remove the requirement to dispatch "close" event on the
surviving port (#3 in paragraph 7.5.3.1). This is the only fix I can see, as
making GC dispatch "close" to fix it from other side would suffer from
basically the same logical problem.

- WBR, Alexey Proskuryakov.

Received on Tuesday, 11 November 2008 12:44:42 UTC