Bug 31698 - MessagePorts always look remotely entangled even when closed.
Summary: MessagePorts always look remotely entangled even when closed.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Andrew Wilson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-11-19 18:16 PST by Andrew Wilson
Modified: 2009-11-25 12:04 PST (History)
3 users (show)

See Also:


Attachments
proposed patch (7.32 KB, patch)
2009-11-23 21:51 PST, Andrew Wilson
no flags Details | Formatted Diff | Diff
Updated patch after removing unnecessary constant (8.32 KB, patch)
2009-11-23 22:16 PST, Andrew Wilson
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
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.