This repository was archived by the owner on Jul 9, 2025. It is now read-only.
File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 88
99#include " AudioSegment.h"
1010#include " mozilla/dom/AudioParam.h"
11+ #include " mozilla/Mutex.h"
1112
1213namespace mozilla {
1314
@@ -151,6 +152,7 @@ class AudioNodeEngine {
151152public:
152153 explicit AudioNodeEngine (dom::AudioNode* aNode)
153154 : mNode(aNode)
155+ , mNodeMutex(" AudioNodeEngine::mNodeMutex" )
154156 {
155157 MOZ_ASSERT (mNode , " The engine is constructed with a null node" );
156158 MOZ_COUNT_CTOR (AudioNodeEngine);
@@ -206,15 +208,25 @@ class AudioNodeEngine {
206208 *aOutput = aInput;
207209 }
208210
211+ Mutex& NodeMutex () { return mNodeMutex ;}
212+
209213 dom::AudioNode* Node () const
210214 {
211- MOZ_ASSERT (NS_IsMainThread() );
215+ mNodeMutex . AssertCurrentThreadOwns ( );
212216 return mNode ;
213217 }
214218
215- protected:
216- friend class dom ::AudioNode;
219+ void ClearNode ()
220+ {
221+ MOZ_ASSERT (NS_IsMainThread());
222+ MOZ_ASSERT (mNode != nullptr );
223+ mNodeMutex .AssertCurrentThreadOwns ();
224+ mNode = nullptr ;
225+ }
226+
227+ private:
217228 dom::AudioNode* mNode ;
229+ Mutex mNodeMutex ;
218230};
219231
220232}
Original file line number Diff line number Diff line change @@ -30,7 +30,15 @@ class AnalyserNodeEngine : public AudioNodeEngine
3030
3131 NS_IMETHOD Run ()
3232 {
33- nsRefPtr<AnalyserNode> node = static_cast <AnalyserNode*>(mStream ->Engine ()->Node ());
33+ nsRefPtr<AnalyserNode> node;
34+ {
35+ // No need to keep holding the lock for the whole duration of this
36+ // function, since we're holding a strong reference to it, so if
37+ // we can obtain the reference, we will hold the node alive in
38+ // this function.
39+ MutexAutoLock lock (mStream ->Engine ()->NodeMutex ());
40+ node = static_cast <AnalyserNode*>(mStream ->Engine ()->Node ());
41+ }
3442 if (node) {
3543 node->AppendChunk (mChunk );
3644 }
@@ -56,7 +64,9 @@ class AnalyserNodeEngine : public AudioNodeEngine
5664 {
5765 *aOutput = aInput;
5866
59- if (mNode &&
67+ MutexAutoLock lock (NodeMutex ());
68+
69+ if (Node () &&
6070 aInput.mChannelData .Length () > 0 ) {
6171 nsRefPtr<TransferBuffer> transfer = new TransferBuffer (aStream, aInput);
6272 NS_DispatchToMainThread (transfer);
Original file line number Diff line number Diff line change @@ -205,11 +205,17 @@ void
205205AudioNode::DestroyMediaStream ()
206206{
207207 if (mStream ) {
208- // Remove the node reference on the engine
209- AudioNodeStream* ns = static_cast <AudioNodeStream*>(mStream .get ());
210- MOZ_ASSERT (ns, " How come we don't have a stream here?" );
211- MOZ_ASSERT (ns->Engine ()->mNode == this , " Invalid node reference" );
212- ns->Engine ()->mNode = nullptr ;
208+ {
209+ // Remove the node reference on the engine, and take care to not
210+ // hold the lock when the stream gets destroyed, because that will
211+ // cause the engine to be destroyed as well, and we don't want to
212+ // be holding the lock as we're trying to destroy it!
213+ AudioNodeStream* ns = static_cast <AudioNodeStream*>(mStream .get ());
214+ MutexAutoLock lock (ns->Engine ()->NodeMutex ());
215+ MOZ_ASSERT (ns, " How come we don't have a stream here?" );
216+ MOZ_ASSERT (ns->Engine ()->Node () == this , " Invalid node reference" );
217+ ns->Engine ()->ClearNode ();
218+ }
213219
214220 mStream ->Destroy ();
215221 mStream = nullptr ;
Original file line number Diff line number Diff line change @@ -37,7 +37,15 @@ class DelayNodeEngine : public AudioNodeEngine
3737
3838 NS_IMETHOD Run ()
3939 {
40- nsRefPtr<DelayNode> node = static_cast <DelayNode*>(mStream ->Engine ()->Node ());
40+ nsRefPtr<DelayNode> node;
41+ {
42+ // No need to keep holding the lock for the whole duration of this
43+ // function, since we're holding a strong reference to it, so if
44+ // we can obtain the reference, we will hold the node alive in
45+ // this function.
46+ MutexAutoLock lock (mStream ->Engine ()->NodeMutex ());
47+ node = static_cast <DelayNode*>(mStream ->Engine ()->Node ());
48+ }
4149 if (node) {
4250 if (mChange == ADDREF ) {
4351 node->mPlayingRef .Take (node);
Original file line number Diff line number Diff line change @@ -140,7 +140,15 @@ class DynamicsCompressorNodeEngine : public AudioNodeEngine
140140
141141 NS_IMETHODIMP Run ()
142142 {
143- nsRefPtr<DynamicsCompressorNode> node = static_cast <DynamicsCompressorNode*>(mStream ->Engine ()->Node ());
143+ nsRefPtr<DynamicsCompressorNode> node;
144+ {
145+ // No need to keep holding the lock for the whole duration of this
146+ // function, since we're holding a strong reference to it, so if
147+ // we can obtain the reference, we will hold the node alive in
148+ // this function.
149+ MutexAutoLock lock (mStream ->Engine ()->NodeMutex ());
150+ node = static_cast <DynamicsCompressorNode*>(mStream ->Engine ()->Node ());
151+ }
144152 if (node) {
145153 AudioParam* reduction = node->Reduction ();
146154 reduction->CancelAllEvents ();
Original file line number Diff line number Diff line change @@ -188,8 +188,10 @@ class ScriptProcessorNodeEngine : public AudioNodeEngine
188188 AudioChunk* aOutput,
189189 bool * aFinished) MOZ_OVERRIDE
190190 {
191+ MutexAutoLock lock (NodeMutex ());
192+
191193 // If our node is dead, just output silence
192- if (!mNode ) {
194+ if (!Node () ) {
193195 aOutput->SetNull (WEBAUDIO_BLOCK_SIZE );
194196 return ;
195197 }
@@ -275,7 +277,15 @@ class ScriptProcessorNodeEngine : public AudioNodeEngine
275277 return NS_OK ;
276278 }
277279
278- nsRefPtr<ScriptProcessorNode> node = static_cast <ScriptProcessorNode*>(mStream ->Engine ()->Node ());
280+ nsRefPtr<ScriptProcessorNode> node;
281+ {
282+ // No need to keep holding the lock for the whole duration of this
283+ // function, since we're holding a strong reference to it, so if
284+ // we can obtain the reference, we will hold the node alive in
285+ // this function.
286+ MutexAutoLock lock (mStream ->Engine ()->NodeMutex ());
287+ node = static_cast <ScriptProcessorNode*>(mStream ->Engine ()->Node ());
288+ }
279289 if (!node) {
280290 return NS_OK ;
281291 }
You can’t perform that action at this time.
0 commit comments