Bug 189021 - MediaDevices should be collectable as soon as its document is stopped
Summary: MediaDevices should be collectable as soon as its document is stopped
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebRTC (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: youenn fablet
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-08-27 15:42 PDT by youenn fablet
Modified: 2018-09-18 11:58 PDT (History)
11 users (show)

See Also:


Attachments
Patch (9.37 KB, patch)
2018-08-27 15:54 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews112 for mac-sierra (3.15 MB, application/zip)
2018-08-27 18:19 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews102 for mac-sierra (2.62 MB, application/zip)
2018-08-27 19:11 PDT, EWS Watchlist
no flags Details
Patch (9.52 KB, patch)
2018-08-27 19:50 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (7.49 KB, patch)
2018-08-27 19:54 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (9.54 KB, patch)
2018-08-28 10:02 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch for landing (3.61 KB, patch)
2018-08-28 13:14 PDT, youenn fablet
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description youenn fablet 2018-08-27 15:42:03 PDT
MediaDevices should be collectable as soon as its document is stopped
Comment 1 youenn fablet 2018-08-27 15:54:42 PDT
Created attachment 348223 [details]
Patch
Comment 2 EWS Watchlist 2018-08-27 18:19:29 PDT
Comment on attachment 348223 [details]
Patch

Attachment 348223 [details] did not pass mac-debug-ews (mac):
Output: https://webkit-queues.webkit.org/results/9003424

New failing tests:
http/tests/media/collect-media-devices.https.html
Comment 3 EWS Watchlist 2018-08-27 18:19:31 PDT
Created attachment 348247 [details]
Archive of layout-test-results from ews112 for mac-sierra

The attached test failures were seen while running run-webkit-tests on the mac-debug-ews.
Bot: ews112  Port: mac-sierra  Platform: Mac OS X 10.12.6
Comment 4 EWS Watchlist 2018-08-27 19:11:07 PDT
Comment on attachment 348223 [details]
Patch

Attachment 348223 [details] did not pass mac-ews (mac):
Output: https://webkit-queues.webkit.org/results/9004309

New failing tests:
http/tests/media/collect-media-devices.https.html
Comment 5 EWS Watchlist 2018-08-27 19:11:09 PDT
Created attachment 348251 [details]
Archive of layout-test-results from ews102 for mac-sierra

The attached test failures were seen while running run-webkit-tests on the mac-ews.
Bot: ews102  Port: mac-sierra  Platform: Mac OS X 10.12.6
Comment 6 youenn fablet 2018-08-27 19:50:46 PDT
Created attachment 348255 [details]
Patch
Comment 7 youenn fablet 2018-08-27 19:54:45 PDT
Created attachment 348256 [details]
Patch
Comment 8 youenn fablet 2018-08-28 10:02:29 PDT
Created attachment 348302 [details]
Patch
Comment 9 youenn fablet 2018-08-28 13:14:11 PDT
Created attachment 348328 [details]
Patch for landing
Comment 10 WebKit Commit Bot 2018-08-28 13:53:25 PDT
Comment on attachment 348328 [details]
Patch for landing

Clearing flags on attachment: 348328

Committed r235438: <https://trac.webkit.org/changeset/235438>
Comment 11 WebKit Commit Bot 2018-08-28 13:53:27 PDT
All reviewed patches have been landed.  Closing bug.
Comment 12 Radar WebKit Bug Importer 2018-08-28 13:54:21 PDT
<rdar://problem/43812760>
Comment 13 Darin Adler 2018-08-28 21:06:26 PDT
Comment on attachment 348302 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=348302&action=review

> Source/WebCore/Modules/mediastream/MediaDevices.cpp:166
>  bool MediaDevices::hasPendingActivity() const
>  {
> -    return scriptExecutionContext() && hasEventListeners(m_eventNames.devicechangeEvent);
> +    return !isContextStopped() && hasEventListeners(m_eventNames.devicechangeEvent);
>  }

Can this new rule be built into ActiveDOMObject instead of of putting it into each override of hasPendingActivity? Or is it not true for all active DOM objects?
Comment 14 youenn fablet 2018-08-28 21:51:07 PDT
> > Source/WebCore/Modules/mediastream/MediaDevices.cpp:166
> >  bool MediaDevices::hasPendingActivity() const
> >  {
> > -    return scriptExecutionContext() && hasEventListeners(m_eventNames.devicechangeEvent);
> > +    return !isContextStopped() && hasEventListeners(m_eventNames.devicechangeEvent);
> >  }
> 
> Can this new rule be built into ActiveDOMObject instead of of putting it
> into each override of hasPendingActivity? Or is it not true for all active
> DOM objects?

I believe we want this to be true and we should build this into ActiveDOMObject.
bug 189018 is a first step in that direction:
- Enforce this to all ActiveDOMObjects that do not override hasPendingActivity
- ASSERT that all ActiveDOMObject::hasPendingActivity return false when context is stopped
If everything succeeds, we could enforce this also for hasPendingActivity overrides.
Comment 15 Geoffrey Garen 2018-08-29 10:06:27 PDT
You could encode this rule mechanically like so:

(*) Make ActiveDOMObject::hasPendingActivity non-virtual, and make it do this:

if (/* document is stopped /*)
    return false;
return hasPendingActivityVirtual();

(*) Rename subclass implementations of hasPendingActivity to hasPendingActivityVirtual.

(*) Remove /* document is stopped */ checks from subclass implementations.
Comment 16 youenn fablet 2018-08-29 10:23:51 PDT
(In reply to Geoffrey Garen from comment #15)
> You could encode this rule mechanically like so:
> 
> (*) Make ActiveDOMObject::hasPendingActivity non-virtual, and make it do
> this:
> 
> if (/* document is stopped /*)
>     return false;
> return hasPendingActivityVirtual();
> 
> (*) Rename subclass implementations of hasPendingActivity to
> hasPendingActivityVirtual.
> 
> (*) Remove /* document is stopped */ checks from subclass implementations.

Sure, one potential issue is that hasPendingActivity be used for other purposes than GC. I was leaning towards adding a non virtual isCollectable method instead.
Comment 17 Geoffrey Garen 2018-08-29 10:49:25 PDT
> Sure, one potential issue is that hasPendingActivity be used for other
> purposes than GC. I was leaning towards adding a non virtual isCollectable
> method instead.

I think that all uses of hasPendingActivity correlate both with GC and document lifetime, and I think I can prove that any use of hasPendingActivity that did not correlate with GC and document lifetime would be a bug.

If you have pending activity but you allow GC, that means that you might fire an event after you collect an object's wrapper and event listeners. That's a compatibility bug.

If you continue pending activity after unloading the document, that means that you have a God-mode activity that the user can't cancel by closing the tab. That's a security / memory leak bug.

Tying document lifetime, GC, and pending activity together in a single function can make that function harder to write -- but it's the good kind of hard because it forces you to ask the hard questions that are required for correct behavior. If isCollectible made it easier not to worry about whether an object had pending activity, it would also make it easier to write incorrect code that collected an object while it still had events to fire, or failed to collect an object even after it was guaranteed not to do any more work or fire any more events.