⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278288 in webkit


Ignore:
Timestamp:
May 31, 2021, 5:08:20 PM (5 years ago)
Author:
Chris Dumez
Message:

Drop PendingActivity data member from BaseAudioContext
https://bugs.webkit.org/show_bug.cgi?id=226445

Reviewed by Darin Adler.

Drop PendingActivity data member from BaseAudioContext and instead have AudioContext / OfflineAudioContext
override virtualHasPendingActivity() to keep their JS wrapper alive. I find that PendingActivity data members
are too error prone and a frequent cause of leaks.

  • Modules/webaudio/AudioContext.cpp:

(WebCore::AudioContext::AudioContext):
(WebCore::AudioContext::startRendering):
(WebCore::AudioContext::mayResumePlayback):
(WebCore::AudioContext::suspendPlayback):
(WebCore::AudioContext::virtualHasPendingActivity const):

  • Modules/webaudio/AudioContext.h:
  • Modules/webaudio/BaseAudioContext.cpp:

(WebCore::BaseAudioContext::clear):
(WebCore::BaseAudioContext::clearPendingActivity): Deleted.
(WebCore::BaseAudioContext::setPendingActivity): Deleted.

  • Modules/webaudio/BaseAudioContext.h:
  • Modules/webaudio/OfflineAudioContext.cpp:

(WebCore::OfflineAudioContext::startRendering):
(WebCore::OfflineAudioContext::resumeRendering):
(WebCore::OfflineAudioContext::didSuspendRendering):
(WebCore::OfflineAudioContext::finishedRendering):
(WebCore::OfflineAudioContext::virtualHasPendingActivity const):
(WebCore::OfflineAudioContext::dispatchEvent): Deleted.

  • Modules/webaudio/OfflineAudioContext.h:
Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r278287 r278288  
     12021-05-31  Chris Dumez  <cdumez@apple.com>
     2
     3        Drop PendingActivity data member from BaseAudioContext
     4        https://bugs.webkit.org/show_bug.cgi?id=226445
     5
     6        Reviewed by Darin Adler.
     7
     8        Drop PendingActivity data member from BaseAudioContext and instead have AudioContext / OfflineAudioContext
     9        override virtualHasPendingActivity() to keep their JS wrapper alive. I find that PendingActivity data members
     10        are too error prone and a frequent cause of leaks.
     11
     12        * Modules/webaudio/AudioContext.cpp:
     13        (WebCore::AudioContext::AudioContext):
     14        (WebCore::AudioContext::startRendering):
     15        (WebCore::AudioContext::mayResumePlayback):
     16        (WebCore::AudioContext::suspendPlayback):
     17        (WebCore::AudioContext::virtualHasPendingActivity const):
     18        * Modules/webaudio/AudioContext.h:
     19        * Modules/webaudio/BaseAudioContext.cpp:
     20        (WebCore::BaseAudioContext::clear):
     21        (WebCore::BaseAudioContext::clearPendingActivity): Deleted.
     22        (WebCore::BaseAudioContext::setPendingActivity): Deleted.
     23        * Modules/webaudio/BaseAudioContext.h:
     24        * Modules/webaudio/OfflineAudioContext.cpp:
     25        (WebCore::OfflineAudioContext::startRendering):
     26        (WebCore::OfflineAudioContext::resumeRendering):
     27        (WebCore::OfflineAudioContext::didSuspendRendering):
     28        (WebCore::OfflineAudioContext::finishedRendering):
     29        (WebCore::OfflineAudioContext::virtualHasPendingActivity const):
     30        (WebCore::OfflineAudioContext::dispatchEvent): Deleted.
     31        * Modules/webaudio/OfflineAudioContext.h:
     32
    1332021-05-31  Chris Dumez  <cdumez@apple.com>
    234
  • trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp

    r278253 r278288  
    116116    , m_mediaSession(PlatformMediaSession::create(PlatformMediaSessionManager::sharedManager(), *this))
    117117{
    118     // According to spec AudioContext must die only after page navigate.
    119     // Lets mark it as ActiveDOMObject with pending activity and unmark it in clear method.
    120     setPendingActivity();
    121 
    122118    constructCommon();
    123119
     
    131127    // Lazy initialization starts rendering so we schedule a task here to make sure lazy initialization
    132128    // ends up happening, even if no audio node gets constructed.
    133     postTask([this] {
     129    postTask([this, pendingActivity = makePendingActivity(*this)] {
    134130        if (!isStopped())
    135131            lazyInitialize();
     
    310306        return;
    311307
    312     setPendingActivity();
    313 
    314     lazyInitialize();
    315     destination().startRendering([this, protectedThis = makeRef(*this)](std::optional<Exception>&& exception) {
     308    lazyInitialize();
     309    destination().startRendering([this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this)](std::optional<Exception>&& exception) {
    316310        if (!exception)
    317311            setState(State::Running);
     
    386380    lazyInitialize();
    387381
    388     destination().resume([this, protectedThis = makeRef(*this)](std::optional<Exception>&& exception) {
     382    destination().resume([this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this)](std::optional<Exception>&& exception) {
    389383        setState(exception ? State::Suspended : State::Running);
    390384    });
     
    472466    lazyInitialize();
    473467
    474     destination().suspend([this, protectedThis = makeRef(*this)](std::optional<Exception>&& exception) {
     468    destination().suspend([this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this)](std::optional<Exception>&& exception) {
    475469        if (exception)
    476470            return;
     
    556550#endif
    557551
     552bool AudioContext::virtualHasPendingActivity() const
     553{
     554    return !isClosed();
     555}
     556
    558557} // namespace WebCore
    559558
  • trunk/Source/WebCore/Modules/webaudio/AudioContext.h

    r278264 r278288  
    143143    void suspend(ReasonForSuspension) final;
    144144    void resume() final;
     145    bool virtualHasPendingActivity() const final;
    145146
    146147    UniqueRef<DefaultAudioDestinationNode> m_destinationNode;
  • trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp

    r278264 r278288  
    180180        m_nodesToDelete = std::exchange(m_nodesMarkedForDeletion, { });
    181181    } while (!m_nodesToDelete.isEmpty());
    182 
    183     clearPendingActivity();
    184182}
    185183
     
    878876}
    879877
    880 void BaseAudioContext::clearPendingActivity()
    881 {
    882     m_pendingActivity = nullptr;
    883 }
    884 
    885 void BaseAudioContext::setPendingActivity()
    886 {
    887     if (!m_pendingActivity)
    888         m_pendingActivity = makePendingActivity(*this);
    889 }
    890 
    891878PeriodicWave& BaseAudioContext::periodicWave(OscillatorType type)
    892879{
  • trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h

    r278264 r278288  
    228228protected:
    229229    explicit BaseAudioContext(Document&);
    230    
    231     void clearPendingActivity();
    232     void setPendingActivity();
    233230
    234231    virtual void uninitialize();
     
    347344    std::unique_ptr<AsyncAudioDecoder> m_audioDecoder;
    348345
    349     RefPtr<PendingActivity<BaseAudioContext>> m_pendingActivity;
    350 
    351346    AudioIOPosition m_outputPosition;
    352347
  • trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp

    r278253 r278288  
    114114        }
    115115
    116         setPendingActivity();
    117116        m_pendingRenderingPromise = WTFMove(promise);
    118117        m_didStartRendering = true;
     
    176175        }
    177176
    178         setPendingActivity();
    179177        setState(State::Running);
    180178        promise->resolve();
     
    196194    setState(State::Suspended);
    197195
    198     clearPendingActivity();
    199 
    200196    RefPtr<DeferredPromise> promise;
    201197    {
     
    218214    });
    219215
     216    // Make sure our JSwrapper stays alive long enough to resolve the promise and queue the completion event.
     217    // Otherwise, setting the state to Closed may cause our JS wrapper to get collected early.
     218    auto protectedJSWrapper = makePendingActivity(*this);
    220219    setState(State::Closed);
    221220
     
    247246}
    248247
    249 void OfflineAudioContext::dispatchEvent(Event& event)
    250 {
    251     BaseAudioContext::dispatchEvent(event);
    252     if (event.eventInterface() == OfflineAudioCompletionEventInterfaceType)
    253         clearPendingActivity();
     248bool OfflineAudioContext::virtualHasPendingActivity() const
     249{
     250    return state() == State::Running;
    254251}
    255252
  • trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.h

    r277858 r278288  
    6161    // ActiveDOMObject
    6262    const char* activeDOMObjectName() const final;
    63 
    64     // EventTarget
    65     void dispatchEvent(Event&) final;
     63    bool virtualHasPendingActivity() const final;
    6664
    6765    void settleRenderingPromise(ExceptionOr<Ref<AudioBuffer>>&&);
Note: See TracChangeset for help on using the changeset viewer.