Index: Source/modules/webaudio/AudioNode.cpp |
diff --git a/Source/modules/webaudio/AudioNode.cpp b/Source/modules/webaudio/AudioNode.cpp |
index 69d6aba4cdba6883452cae38d42eb9b4335ef244..dc422d2f00b98cd903f420a2b3a49f6ae11a1295 100644 |
--- a/Source/modules/webaudio/AudioNode.cpp |
+++ b/Source/modules/webaudio/AudioNode.cpp |
@@ -55,7 +55,6 @@ AudioNode::AudioNode(AudioContext* context, float sampleRate) |
, m_lastNonSilentTime(-1) |
, m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefCounted class) |
, m_connectionRefCount(0) |
- , m_wasDisconnected(false) |
, m_isMarkedForDeletion(false) |
, m_isDisabled(false) |
, m_channelCount(2) |
@@ -527,9 +526,39 @@ void AudioNode::deref() |
void AudioNode::breakConnection() |
{ |
+ // The actually work for deref happens completely within the audio context's |
Raymond Toy
2014/07/14 16:43:01
Typo: "actually" -> "actual"
tkent
2014/07/15 01:19:23
Done. Also fixed it in deref().
|
+ // graph lock. In the case of the audio thread, we must use a tryLock to |
+ // avoid glitches. |
+ bool hasLock = false; |
+ bool mustReleaseLock = false; |
+ |
+ if (context()->isAudioThread()) { |
+ // Real-time audio thread must not contend lock (to avoid glitches). |
+ hasLock = context()->tryLock(mustReleaseLock); |
+ } else { |
+ context()->lock(mustReleaseLock); |
+ hasLock = true; |
+ } |
+ |
+ if (hasLock) { |
+ breakConnectionWithLock(); |
+ |
+ if (mustReleaseLock) |
+ context()->unlock(); |
+ } else { |
+ // We were unable to get the lock, so put this in a list to finish up |
+ // later. |
+ ASSERT(context()->isAudioThread()); |
+ context()->addDeferredBreakConnection(*this); |
+ } |
+} |
+ |
+void AudioNode::breakConnectionWithLock() |
+{ |
ASSERT(m_normalRefCount > 0); |
atomicDecrement(&m_connectionRefCount); |
- m_wasDisconnected = true; |
+ if (m_connectionRefCount == 0 && m_normalRefCount > 1) |
+ disableOutputsIfNecessary(); |
} |
void AudioNode::finishDeref() |
@@ -543,12 +572,6 @@ void AudioNode::finishDeref() |
fprintf(stderr, "%p: %d: AudioNode::deref() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount); |
#endif |
- if (m_wasDisconnected) { |
- if (m_connectionRefCount == 0 && m_normalRefCount > 0) |
- disableOutputsIfNecessary(); |
- m_wasDisconnected = false; |
- } |
- |
if (!m_normalRefCount && !m_isMarkedForDeletion) { |
// All references are gone - we need to go away. |
for (unsigned i = 0; i < m_outputs.size(); ++i) |