Index: Source/modules/webaudio/AudioContext.cpp |
diff --git a/Source/modules/webaudio/AudioContext.cpp b/Source/modules/webaudio/AudioContext.cpp |
index 54f7637fbe38c9998269b4929c17998691a8f5a8..c83cd758fc603b2600c1117d77e63367f65402c7 100644 |
--- a/Source/modules/webaudio/AudioContext.cpp |
+++ b/Source/modules/webaudio/AudioContext.cpp |
@@ -111,6 +111,8 @@ AudioContext::AudioContext(Document* document) |
, m_connectionCount(0) |
, m_didInitializeContextGraphMutex(false) |
, m_audioThread(0) |
+ , m_lastZombie(nullptr) |
+ , m_lastRemovableZombie(nullptr) |
, m_isOfflineContext(false) |
, m_contextState(Suspended) |
, m_cachedSampleFrame(0) |
@@ -133,6 +135,8 @@ AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t |
, m_connectionCount(0) |
, m_didInitializeContextGraphMutex(false) |
, m_audioThread(0) |
+ , m_lastZombie(nullptr) |
+ , m_lastRemovableZombie(nullptr) |
, m_isOfflineContext(true) |
, m_contextState(Suspended) |
, m_cachedSampleFrame(0) |
@@ -169,6 +173,7 @@ void AudioContext::initialize() |
if (isInitialized()) |
return; |
+ ThreadState::current()->addMarkingTask(this); |
FFTFrame::initialize(); |
m_listener = AudioListener::create(); |
@@ -239,6 +244,12 @@ void AudioContext::uninitialize() |
m_listener->waitForHRTFDatabaseLoaderThreadCompletion(); |
clear(); |
+ |
+ ThreadState::current()->removeMarkingTask(this); |
+ if (m_lastZombie) |
+ ThreadState::current()->purifyZombies(); |
+ m_lastZombie = nullptr; |
+ m_lastRemovableZombie = nullptr; |
} |
void AudioContext::stop() |
@@ -985,6 +996,8 @@ void AudioContext::handlePostRenderTasks() |
// Dynamically clean up nodes which are no longer needed. |
derefFinishedSourceNodes(); |
+ m_lastRemovableZombie = m_lastZombie; |
+ |
// Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutputs. |
handleDirtyAudioSummingJunctions(); |
handleDirtyAudioNodeOutputs(); |
@@ -1281,14 +1294,7 @@ DEFINE_TRACE(AudioContext) |
visitor->trace(m_renderTarget); |
visitor->trace(m_destinationNode); |
visitor->trace(m_listener); |
- // trace() can be called in AudioContext constructor, and |
- // m_contextGraphMutex might be unavailable. |
- if (m_didInitializeContextGraphMutex) { |
- AutoLocker lock(this); |
- visitor->trace(m_referencedNodes); |
- } else { |
- visitor->trace(m_referencedNodes); |
- } |
+ visitor->trace(m_referencedNodes); |
visitor->trace(m_resumeResolvers); |
visitor->trace(m_suspendResolvers); |
visitor->trace(m_liveNodes); |
@@ -1365,6 +1371,29 @@ ScriptPromise AudioContext::closeContext(ScriptState* scriptState) |
return promise; |
} |
+void AudioContext::setLastZombie(void* object) |
+{ |
+ ASSERT(isGraphOwner()); |
+ m_lastZombie = object; |
+} |
+ |
+void AudioContext::willStartMarking(ThreadState& threadState) |
+{ |
+ lock(); |
+ if (!m_lastRemovableZombie) |
+ return; |
+ if (m_lastZombie != m_lastRemovableZombie) |
+ return; |
+ threadState.purifyZombies(); |
+ m_lastZombie = nullptr; |
+ m_lastRemovableZombie = nullptr; |
+} |
+ |
+void AudioContext::didFinishMarking(ThreadState&) |
+{ |
+ unlock(); |
+} |
+ |
} // namespace blink |
#endif // ENABLE(WEB_AUDIO) |