Index: Source/modules/webaudio/PannerNode.cpp |
diff --git a/Source/modules/webaudio/PannerNode.cpp b/Source/modules/webaudio/PannerNode.cpp |
index fcebe1273dca1da2529be7de71891fdccf383330..e15e7b49376efb5385fcffae88846f5079b202a7 100644 |
--- a/Source/modules/webaudio/PannerNode.cpp |
+++ b/Source/modules/webaudio/PannerNode.cpp |
@@ -85,8 +85,12 @@ void PannerNode::pullInputs(size_t framesToProcess) |
if (m_connectionCount != context()->connectionCount()) { |
m_connectionCount = context()->connectionCount(); |
- // Recursively go through all nodes connected to us. |
- notifyAudioSourcesConnectedToNode(this); |
+ // A map for keeping track if we have visited a node or not. This prevents feedback loops |
+ // from recursing infinitely. See crbug.com/331446. |
+ HashMap<AudioNode*, bool> visitedNodes; |
+ |
+ // Recursively go through all nodes connected to us |
+ notifyAudioSourcesConnectedToNode(this, visitedNodes); |
} |
AudioNode::pullInputs(framesToProcess); |
@@ -386,7 +390,7 @@ float PannerNode::distanceConeGain() |
return float(distanceGain * coneGain); |
} |
-void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node) |
+void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashMap<AudioNode*, bool>& visitedNodes) |
{ |
ASSERT(node); |
if (!node) |
@@ -405,7 +409,14 @@ void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node) |
for (unsigned j = 0; j < input->numberOfRenderingConnections(); ++j) { |
AudioNodeOutput* connectedOutput = input->renderingOutput(j); |
AudioNode* connectedNode = connectedOutput->node(); |
- notifyAudioSourcesConnectedToNode(connectedNode); // recurse |
+ HashMap<AudioNode*, bool>::iterator iterator = visitedNodes.find(connectedNode); |
+ |
+ // If we've seen this node already, we don't need to process it again. Otherwise, |
+ // mark it as visited and recurse through the node looking for sources. |
+ if (iterator == visitedNodes.end()) { |
+ visitedNodes.set(connectedNode, true); |
+ notifyAudioSourcesConnectedToNode(connectedNode, visitedNodes); // recurse |
+ } |
} |
} |
} |