Title: [278288] trunk/Source/WebCore
Revision
278288
Author
cdu...@apple.com
Date
2021-05-31 17:08:20 -0700 (Mon, 31 May 2021)

Log 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:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (278287 => 278288)


--- trunk/Source/WebCore/ChangeLog	2021-06-01 00:07:14 UTC (rev 278287)
+++ trunk/Source/WebCore/ChangeLog	2021-06-01 00:08:20 UTC (rev 278288)
@@ -1,5 +1,37 @@
 2021-05-31  Chris Dumez  <cdu...@apple.com>
 
+        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:
+
+2021-05-31  Chris Dumez  <cdu...@apple.com>
+
         Fix thread safety issues in AudioBufferSourceNode
         https://bugs.webkit.org/show_bug.cgi?id=226448
 

Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp (278287 => 278288)


--- trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp	2021-06-01 00:07:14 UTC (rev 278287)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp	2021-06-01 00:08:20 UTC (rev 278288)
@@ -115,10 +115,6 @@
     , m_destinationNode(makeUniqueRef<DefaultAudioDestinationNode>(*this, contextOptions.sampleRate))
     , m_mediaSession(PlatformMediaSession::create(PlatformMediaSessionManager::sharedManager(), *this))
 {
-    // According to spec AudioContext must die only after page navigate.
-    // Lets mark it as ActiveDOMObject with pending activity and unmark it in clear method.
-    setPendingActivity();
-
     constructCommon();
 
     // Initialize the destination node's muted state to match the page's current muted state.
@@ -130,7 +126,7 @@
     // Unlike OfflineAudioContext, AudioContext does not require calling resume() to start rendering.
     // Lazy initialization starts rendering so we schedule a task here to make sure lazy initialization
     // ends up happening, even if no audio node gets constructed.
-    postTask([this] {
+    postTask([this, pendingActivity = makePendingActivity(*this)] {
         if (!isStopped())
             lazyInitialize();
     });
@@ -309,10 +305,8 @@
     if (isStopped() || !willBeginPlayback() || m_wasSuspendedByScript)
         return;
 
-    setPendingActivity();
-
     lazyInitialize();
-    destination().startRendering([this, protectedThis = makeRef(*this)](std::optional<Exception>&& exception) {
+    destination().startRendering([this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this)](std::optional<Exception>&& exception) {
         if (!exception)
             setState(State::Running);
     });
@@ -385,7 +379,7 @@
 
     lazyInitialize();
 
-    destination().resume([this, protectedThis = makeRef(*this)](std::optional<Exception>&& exception) {
+    destination().resume([this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this)](std::optional<Exception>&& exception) {
         setState(exception ? State::Suspended : State::Running);
     });
 }
@@ -471,7 +465,7 @@
 
     lazyInitialize();
 
-    destination().suspend([this, protectedThis = makeRef(*this)](std::optional<Exception>&& exception) {
+    destination().suspend([this, protectedThis = makeRef(*this), pendingActivity = makePendingActivity(*this)](std::optional<Exception>&& exception) {
         if (exception)
             return;
 
@@ -555,6 +549,11 @@
 
 #endif
 
+bool AudioContext::virtualHasPendingActivity() const
+{
+    return !isClosed();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEB_AUDIO)

Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.h (278287 => 278288)


--- trunk/Source/WebCore/Modules/webaudio/AudioContext.h	2021-06-01 00:07:14 UTC (rev 278287)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.h	2021-06-01 00:08:20 UTC (rev 278288)
@@ -142,6 +142,7 @@
     const char* activeDOMObjectName() const final;
     void suspend(ReasonForSuspension) final;
     void resume() final;
+    bool virtualHasPendingActivity() const final;
 
     UniqueRef<DefaultAudioDestinationNode> m_destinationNode;
     std::unique_ptr<PlatformMediaSession> m_mediaSession;

Modified: trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp (278287 => 278288)


--- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp	2021-06-01 00:07:14 UTC (rev 278287)
+++ trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp	2021-06-01 00:08:20 UTC (rev 278288)
@@ -179,8 +179,6 @@
         deleteMarkedNodes();
         m_nodesToDelete = std::exchange(m_nodesMarkedForDeletion, { });
     } while (!m_nodesToDelete.isEmpty());
-
-    clearPendingActivity();
 }
 
 void BaseAudioContext::uninitialize()
@@ -877,17 +875,6 @@
         m_scriptExecutionContext->addConsoleMessage(source, level, message);
 }
 
-void BaseAudioContext::clearPendingActivity()
-{
-    m_pendingActivity = nullptr;
-}
-
-void BaseAudioContext::setPendingActivity()
-{
-    if (!m_pendingActivity)
-        m_pendingActivity = makePendingActivity(*this);
-}
-
 PeriodicWave& BaseAudioContext::periodicWave(OscillatorType type)
 {
     switch (type) {

Modified: trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h (278287 => 278288)


--- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h	2021-06-01 00:07:14 UTC (rev 278287)
+++ trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h	2021-06-01 00:08:20 UTC (rev 278288)
@@ -227,9 +227,6 @@
 
 protected:
     explicit BaseAudioContext(Document&);
-    
-    void clearPendingActivity();
-    void setPendingActivity();
 
     virtual void uninitialize();
 
@@ -346,8 +343,6 @@
 
     std::unique_ptr<AsyncAudioDecoder> m_audioDecoder;
 
-    RefPtr<PendingActivity<BaseAudioContext>> m_pendingActivity;
-
     AudioIOPosition m_outputPosition;
 
     HashMap<String, Vector<AudioParamDescriptor>> m_parameterDescriptorMap;

Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp (278287 => 278288)


--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp	2021-06-01 00:07:14 UTC (rev 278287)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp	2021-06-01 00:08:20 UTC (rev 278288)
@@ -113,7 +113,6 @@
             return;
         }
 
-        setPendingActivity();
         m_pendingRenderingPromise = WTFMove(promise);
         m_didStartRendering = true;
         setState(State::Running);
@@ -175,7 +174,6 @@
             return;
         }
 
-        setPendingActivity();
         setState(State::Running);
         promise->resolve();
     });
@@ -195,8 +193,6 @@
 {
     setState(State::Suspended);
 
-    clearPendingActivity();
-
     RefPtr<DeferredPromise> promise;
     {
         Locker locker { graphLock() };
@@ -217,6 +213,9 @@
         clear();
     });
 
+    // Make sure our JSwrapper stays alive long enough to resolve the promise and queue the completion event.
+    // Otherwise, setting the state to Closed may cause our JS wrapper to get collected early.
+    auto protectedJSWrapper = makePendingActivity(*this);
     setState(State::Closed);
 
     // Avoid firing the event if the document has already gone away.
@@ -246,11 +245,9 @@
     promise->resolve<IDLInterface<AudioBuffer>>(result.releaseReturnValue());
 }
 
-void OfflineAudioContext::dispatchEvent(Event& event)
+bool OfflineAudioContext::virtualHasPendingActivity() const
 {
-    BaseAudioContext::dispatchEvent(event);
-    if (event.eventInterface() == OfflineAudioCompletionEventInterfaceType)
-        clearPendingActivity();
+    return state() == State::Running;
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.h (278287 => 278288)


--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.h	2021-06-01 00:07:14 UTC (rev 278287)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.h	2021-06-01 00:08:20 UTC (rev 278288)
@@ -60,10 +60,8 @@
 
     // ActiveDOMObject
     const char* activeDOMObjectName() const final;
+    bool virtualHasPendingActivity() const final;
 
-    // EventTarget
-    void dispatchEvent(Event&) final;
-
     void settleRenderingPromise(ExceptionOr<Ref<AudioBuffer>>&&);
     void uninitialize() final;
     bool isOfflineContext() const final { return true; }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to