Changeset 252497 in webkit


Ignore:
Timestamp:
Nov 15, 2019 12:08:08 PM (4 years ago)
Author:
Chris Dumez
Message:

Regression: http/tests/navigation/page-cache-getUserMedia-pending-promise.html is crashing in Debug
https://bugs.webkit.org/show_bug.cgi?id=204232

Reviewed by Eric Carlson.

No new tests, covered by http/tests/navigation/page-cache-getUserMedia-pending-promise.html.

  • Modules/mediastream/MediaStreamTrack.cpp:

(WebCore::MediaStreamTrack::create):
(WebCore::MediaStreamTrack::MediaStreamTrack):
Call suspendIfNeeded() in the factory and not in the constructor. It is never safe to call
suspendIfNeeded() from inside the constructor because it may call the suspend() method, which
may ref |this|.

  • Modules/mediastream/UserMediaRequest.cpp:

(WebCore::UserMediaRequest::allow):
Queue a task on the HTML event loop when the user media request is approved. This way, if the
page is suspended when this happens, we delay constructing the media stream (among other things)
until the page actually resumes.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r252487 r252497  
     12019-11-15  Chris Dumez  <cdumez@apple.com>
     2
     3        Regression: http/tests/navigation/page-cache-getUserMedia-pending-promise.html is crashing in Debug
     4        https://bugs.webkit.org/show_bug.cgi?id=204232
     5
     6        Reviewed by Eric Carlson.
     7
     8        No new tests, covered by http/tests/navigation/page-cache-getUserMedia-pending-promise.html.
     9
     10        * Modules/mediastream/MediaStreamTrack.cpp:
     11        (WebCore::MediaStreamTrack::create):
     12        (WebCore::MediaStreamTrack::MediaStreamTrack):
     13        Call suspendIfNeeded() in the factory and not in the constructor. It is never safe to call
     14        suspendIfNeeded() from inside the constructor because it may call the suspend() method, which
     15        may ref |this|.
     16
     17        * Modules/mediastream/UserMediaRequest.cpp:
     18        (WebCore::UserMediaRequest::allow):
     19        Queue a task on the HTML event loop when the user media request is approved. This way, if the
     20        page is suspended when this happens, we delay constructing the media stream (among other things)
     21        until the page actually resumes.
     22
    1232019-11-15  Zalan Bujtas  <zalan@apple.com>
    224
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp

    r252337 r252497  
    6363Ref<MediaStreamTrack> MediaStreamTrack::create(ScriptExecutionContext& context, Ref<MediaStreamTrackPrivate>&& privateTrack)
    6464{
    65     return adoptRef(*new MediaStreamTrack(context, WTFMove(privateTrack)));
     65    auto track = adoptRef(*new MediaStreamTrack(context, WTFMove(privateTrack)));
     66    track->suspendIfNeeded();
     67    return track;
    6668}
    6769
     
    7476{
    7577    ALWAYS_LOG(LOGIDENTIFIER);
    76     suspendIfNeeded();
    7778
    7879    m_private->addObserver(*this);
  • trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp

    r252263 r252497  
    232232    RELEASE_LOG(MediaStream, "UserMediaRequest::allow %s %s", audioDevice ? audioDevice.persistentId().utf8().data() : "", videoDevice ? videoDevice.persistentId().utf8().data() : "");
    233233
    234     auto callback = [this, protector = makePendingActivity(*this), completionHandler = WTFMove(completionHandler)](RefPtr<MediaStreamPrivate>&& privateStream) mutable {
    235         auto scopeExit = makeScopeExit([completionHandler = WTFMove(completionHandler)]() mutable {
    236             completionHandler();
    237         });
    238         if (isContextStopped())
     234    queueTaskKeepingObjectAlive(*this, TaskSource::UserInteraction, [this, audioDevice = WTFMove(audioDevice), videoDevice = WTFMove(videoDevice), deviceIdentifierHashSalt = WTFMove(deviceIdentifierHashSalt), completionHandler = WTFMove(completionHandler)]() mutable {
     235        auto callback = [this, protector = makePendingActivity(*this), completionHandler = WTFMove(completionHandler)](RefPtr<MediaStreamPrivate>&& privateStream) mutable {
     236            auto scopeExit = makeScopeExit([completionHandler = WTFMove(completionHandler)]() mutable {
     237                completionHandler();
     238            });
     239            if (isContextStopped())
     240                return;
     241
     242            if (!privateStream) {
     243                RELEASE_LOG(MediaStream, "UserMediaRequest::allow failed to create media stream!");
     244                deny(MediaAccessDenialReason::HardwareError);
     245                return;
     246            }
     247
     248            auto& document = downcast<Document>(*m_scriptExecutionContext);
     249            privateStream->monitorOrientation(document.orientationNotifier());
     250
     251            auto stream = MediaStream::create(document, privateStream.releaseNonNull());
     252            stream->startProducingData();
     253
     254            if (!isMediaStreamCorrectlyStarted(stream)) {
     255                deny(MediaAccessDenialReason::HardwareError);
     256                return;
     257            }
     258
     259            ASSERT(document.isCapturing());
     260            stream->document()->setHasCaptureMediaStreamTrack();
     261            m_promise->resolve(WTFMove(stream));
     262        };
     263
     264        auto& document = downcast<Document>(*scriptExecutionContext());
     265        document.setDeviceIDHashSalt(deviceIdentifierHashSalt);
     266
     267        RealtimeMediaSourceCenter::singleton().createMediaStream(document.logger(), WTFMove(callback), WTFMove(deviceIdentifierHashSalt), WTFMove(audioDevice), WTFMove(videoDevice), m_request);
     268
     269        if (!m_scriptExecutionContext)
    239270            return;
    240271
    241         if (!privateStream) {
    242             RELEASE_LOG(MediaStream, "UserMediaRequest::allow failed to create media stream!");
    243             deny(MediaAccessDenialReason::HardwareError);
    244             return;
    245         }
    246 
    247         auto& document = downcast<Document>(*m_scriptExecutionContext);
    248         privateStream->monitorOrientation(document.orientationNotifier());
    249 
    250         auto stream = MediaStream::create(document, privateStream.releaseNonNull());
    251         stream->startProducingData();
    252 
    253         if (!isMediaStreamCorrectlyStarted(stream)) {
    254             deny(MediaAccessDenialReason::HardwareError);
    255             return;
    256         }
    257 
    258         ASSERT(document.isCapturing());
    259         stream->document()->setHasCaptureMediaStreamTrack();
    260         m_promise->resolve(WTFMove(stream));
    261     };
    262 
    263     auto& document = downcast<Document>(*scriptExecutionContext());
    264     document.setDeviceIDHashSalt(deviceIdentifierHashSalt);
    265 
    266     RealtimeMediaSourceCenter::singleton().createMediaStream(document.logger(), WTFMove(callback), WTFMove(deviceIdentifierHashSalt), WTFMove(audioDevice), WTFMove(videoDevice), m_request);
    267 
    268     if (!m_scriptExecutionContext)
    269         return;
    270 
    271272#if ENABLE(WEB_RTC)
    272     if (auto* page = document.page())
    273         page->rtcController().disableICECandidateFilteringForDocument(document);
     273        if (auto* page = document.page())
     274            page->rtcController().disableICECandidateFilteringForDocument(document);
    274275#endif
     276    });
    275277}
    276278
Note: See TracChangeset for help on using the changeset viewer.