Bug 31698

Summary: MessagePorts always look remotely entangled even when closed.
Product: WebKit Reporter: Andrew Wilson <atwilson>
Component: WebCore Misc.Assignee: Andrew Wilson <atwilson>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, commit-queue, jam
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: OS X 10.5   
Attachments:
Description Flags
proposed patch
none
Updated patch after removing unnecessary constant none

Description Andrew Wilson 2009-11-19 18:16:13 PST
We use the following idiom to see if a port is remotely entangled:

port->isEntangled() && !port->locallyEntangledPort()

The problem is that isEntangled() returns true even when a port is closed, so a worker that is closed looks like it is remotely entangled.

On JSC-based platforms (e.g. Safari), the port will be closed/freed when the parent context exits. Since a remotely entangled MessagePort is sufficient to keep a worker alive, a fire-and-forget worker that just contains this code:

var channel = new MessageChannel();
channel.port1.close();

...will stay alive until the parent document shuts down.

On Chromium, ports leak until the parent *process* closes, thanks to this line in V8GCController.cpp:

        if (port1->isEntangled() && !port2)
            wrapper.ClearWeak();

We need a better way to figure out if a port is remotely entangled - one option would be to have isEntangled() return false if the worker has been closed. Right now, the code is a little fuzzy about the distinction between a disentangled/closed port and a *cloned* port - we'll need to clear that up as well as part of this fix (for example, it's OK to pass a disentangled port to postMessage(), but it's not OK to pass a cloned port to postMessage()).
Comment 1 Andrew Wilson 2009-11-23 21:51:32 PST
Created attachment 43748 [details]
proposed patch

The old V8 GC code relied on the fact that a port could not be disentangled during GC, which is clearly incorrect. I updated/simplified this code to do the right thing now (add a reference to entangled ports at the start of GC, and remove the reference from all referenced ports at the end).
Comment 2 Andrew Wilson 2009-11-23 22:16:23 PST
Created attachment 43749 [details]
Updated patch after removing unnecessary constant

We no longer need to keep around an extra field to store a reference to the locally entangled port, so I removed it.
Comment 3 WebKit Commit Bot 2009-11-25 12:04:36 PST
Comment on attachment 43749 [details]
Updated patch after removing unnecessary constant

Clearing flags on attachment: 43749

Committed r51392: <http://trac.webkit.org/changeset/51392>
Comment 4 WebKit Commit Bot 2009-11-25 12:04:41 PST
All reviewed patches have been landed.  Closing bug.