Bug 864351 - Hold on to a SelfReference for ScriptProcessorNodes to make sure that they won't go away prematurely if they're used as source nodes; r=padenot

This commit is contained in:
Ehsan Akhgari 2013-04-22 21:23:54 -04:00
parent 1ca2b253f5
commit 6b1729abc9
5 changed files with 58 additions and 3 deletions

View File

@ -141,6 +141,7 @@ AudioContext::CreateScriptProcessor(uint32_t aBufferSize,
nsRefPtr<ScriptProcessorNode> scriptProcessor =
new ScriptProcessorNode(this, aBufferSize, aNumberOfInputChannels,
aNumberOfOutputChannels);
mScriptProcessorNodes.AppendElement(scriptProcessor);
return scriptProcessor.forget();
}
@ -245,6 +246,12 @@ AudioContext::UnregisterPannerNode(PannerNode* aNode)
mPannerNodes.RemoveElement(aNode);
}
void
AudioContext::UnregisterScriptProcessorNode(ScriptProcessorNode* aNode)
{
mScriptProcessorNodes.RemoveElement(aNode);
}
void
AudioContext::UpdatePannerSource()
{
@ -286,6 +293,11 @@ AudioContext::Shutdown()
ErrorResult rv;
mAudioBufferSourceNodes[i]->Stop(0.0, rv);
}
// Stop all script processor nodes, to make sure that they release
// their self-references.
for (uint32_t i = 0; i < mScriptProcessorNodes.Length(); ++i) {
mScriptProcessorNodes[i]->Stop();
}
}
void

View File

@ -151,6 +151,7 @@ public:
MediaStream* DestinationStream() const;
void UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode);
void UnregisterPannerNode(PannerNode* aNode);
void UnregisterScriptProcessorNode(ScriptProcessorNode* aNode);
void UpdatePannerSource();
JSContext* GetJSContext() const;
@ -170,6 +171,7 @@ private:
// to compute the doppler shift. Those are weak pointers.
nsTArray<PannerNode*> mPannerNodes;
nsTArray<AudioBufferSourceNode*> mAudioBufferSourceNodes;
nsTArray<ScriptProcessorNode*> mScriptProcessorNodes;
};
}

View File

@ -105,10 +105,10 @@ public:
return mContext;
}
void Connect(AudioNode& aDestination, uint32_t aOutput,
uint32_t aInput, ErrorResult& aRv);
virtual void Connect(AudioNode& aDestination, uint32_t aOutput,
uint32_t aInput, ErrorResult& aRv);
void Disconnect(uint32_t aOutput, ErrorResult& aRv);
virtual void Disconnect(uint32_t aOutput, ErrorResult& aRv);
// The following two virtual methods must be implemented by each node type
// to provide their number of input and output ports. These numbers are

View File

@ -19,6 +19,15 @@
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ScriptProcessorNode, AudioNode)
if (tmp->Context()) {
tmp->Context()->UnregisterScriptProcessorNode(tmp);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ScriptProcessorNode, AudioNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ScriptProcessorNode)
NS_INTERFACE_MAP_END_INHERITING(AudioNode)
@ -357,6 +366,13 @@ ScriptProcessorNode::ScriptProcessorNode(AudioContext* aContext,
engine->SetSourceStream(static_cast<AudioNodeStream*> (mStream.get()));
}
ScriptProcessorNode::~ScriptProcessorNode()
{
if (Context()) {
Context()->UnregisterScriptProcessorNode(this);
}
}
JSObject*
ScriptProcessorNode::WrapObject(JSContext* aCx, JSObject* aScope)
{

View File

@ -27,8 +27,10 @@ public:
uint32_t aBufferSize,
uint32_t aNumberOfInputChannels,
uint32_t aNumberOfOutputChannels);
virtual ~ScriptProcessorNode();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ScriptProcessorNode, AudioNode)
IMPL_EVENT_HANDLER(audioprocess)
@ -39,6 +41,23 @@ public:
return true;
}
virtual void Connect(AudioNode& aDestination, uint32_t aOutput,
uint32_t aInput, ErrorResult& aRv) MOZ_OVERRIDE
{
AudioNode::Connect(aDestination, aOutput, aInput, aRv);
if (!aRv.Failed()) {
mPlayingRef.Take(this);
}
}
virtual void Disconnect(uint32_t aOutput, ErrorResult& aRv) MOZ_OVERRIDE
{
AudioNode::Disconnect(aOutput, aRv);
if (!aRv.Failed()) {
mPlayingRef.Drop(this);
}
}
uint32_t BufferSize() const
{
return mBufferSize;
@ -56,10 +75,16 @@ public:
using nsDOMEventTargetHelper::DispatchTrustedEvent;
void Stop()
{
mPlayingRef.Drop(this);
}
private:
nsAutoPtr<SharedBuffers> mSharedBuffers;
const uint32_t mBufferSize;
const uint32_t mNumberOfOutputChannels;
SelfReference<ScriptProcessorNode> mPlayingRef; // a reference to self while planing
};
}