Index: Source/modules/webaudio/AudioNode.cpp |
diff --git a/Source/modules/webaudio/AudioNode.cpp b/Source/modules/webaudio/AudioNode.cpp |
index 733bccb840c23edeca0a71922f2a4f7354d887d0..2860b109329d2c8522f1af83995d4e56b3b91aa0 100644 |
--- a/Source/modules/webaudio/AudioNode.cpp |
+++ b/Source/modules/webaudio/AudioNode.cpp |
@@ -53,7 +53,9 @@ AudioNode::AudioNode(AudioContext* context, float sampleRate) |
, m_lastProcessingTime(-1) |
, m_lastNonSilentTime(-1) |
#if !ENABLE(OILPAN) |
- , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefCounted class) |
+ // Start with 0, because we use m_normalRefCount only for ref() and deref() |
+ // that are explicitly called. Other references are managed by Oilpan. |
+ , m_normalRefCount(0) |
#endif |
, m_connectionRefCount(0) |
, m_isDisabled(false) |
@@ -63,9 +65,7 @@ AudioNode::AudioNode(AudioContext* context, float sampleRate) |
, m_channelInterpretation(AudioBus::Speakers) |
{ |
ScriptWrappable::init(this); |
-#if ENABLE(OILPAN) |
m_context->registerLiveNode(*this); |
-#endif |
#if DEBUG_AUDIONODE_REFERENCES |
if (!s_isNodeCountInitialized) { |
s_isNodeCountInitialized = true; |
@@ -176,7 +176,7 @@ void AudioNode::addInput() |
m_inputs.append(AudioNodeInput::create(*this)); |
} |
-void AudioNode::addOutput(PassOwnPtrWillBeRawPtr<AudioNodeOutput> output) |
+void AudioNode::addOutput(AudioNodeOutput* output) |
{ |
m_outputs.append(output); |
} |
@@ -499,7 +499,13 @@ void AudioNode::disableOutputsIfNecessary() |
#if !ENABLE(OILPAN) |
void AudioNode::ref() |
{ |
- atomicIncrement(&m_normalRefCount); |
+ // We create a self-keep-alive persistent handle when the first ref() |
+ // is called. |
+ if (atomicIncrement(&m_normalRefCount) == 1) { |
+ ASSERT(!m_keepAlive); |
+ m_keepAlive = this; |
+ } |
+ ASSERT(m_keepAlive); |
#if DEBUG_AUDIONODE_REFERENCES |
fprintf(stderr, "%p: %d: AudioNode::ref() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount); |
@@ -544,12 +550,6 @@ void AudioNode::deref() |
ASSERT(context()->isAudioThread()); |
context()->addDeferredFinishDeref(this); |
} |
- |
- // Once AudioContext::uninitialize() is called there's no more chances for deleteMarkedNodes() to get called, so we call here. |
- // We can't call in AudioContext::~AudioContext() since it will never be called as long as any AudioNode is alive |
- // because AudioNodes keep a reference to the context. |
- if (!context()->isInitialized()) |
- context()->deleteMarkedNodes(); |
} |
#endif |
@@ -585,9 +585,6 @@ void AudioNode::breakConnection() |
void AudioNode::breakConnectionWithLock() |
{ |
atomicDecrement(&m_connectionRefCount); |
-#if !ENABLE(OILPAN) |
- ASSERT(m_normalRefCount > 0); |
-#endif |
if (!m_connectionRefCount) |
disableOutputsIfNecessary(); |
} |
@@ -605,9 +602,9 @@ void AudioNode::finishDeref() |
#endif |
if (!m_normalRefCount) { |
- // Mark for deletion at end of each render quantum or when context shuts |
- // down. |
- context()->markForDeletion(this); |
+ // This self-keep-alive handle can be resurrected when the ref() is |
+ // called again. |
+ m_keepAlive = nullptr; |
} |
} |
#endif |