diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/PendingProgress.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/PendingProgress.cs index e62d5ab335e..269c5252fb1 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/PendingProgress.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/PendingProgress.cs @@ -9,6 +9,7 @@ using System.Management.Automation; using System.Management.Automation.Host; using System.Management.Automation.Internal; +using System.Threading; using Dbg = System.Management.Automation.Diagnostics; @@ -204,21 +205,29 @@ class PendingProgress void RemoveNode(ArrayList nodes, int indexToRemove) { + _pendingProgressLock.EnterWriteLock(); + try + { #if DEBUG || ASSERTIONS_TRACE - ProgressNode nodeToRemove = (ProgressNode)nodes[indexToRemove]; + ProgressNode nodeToRemove = (ProgressNode)nodes[indexToRemove]; - Dbg.Assert(nodes != null, "can't remove nodes from a null list"); - Dbg.Assert(indexToRemove < nodes.Count, "index is not in list"); - Dbg.Assert(nodes[indexToRemove] != null, "no node at specified index"); - Dbg.Assert(nodeToRemove.Children == null || nodeToRemove.Children.Count == 0, "can't remove a node with children"); + Dbg.Assert(nodes != null, "can't remove nodes from a null list"); + Dbg.Assert(indexToRemove < nodes.Count, "index is not in list"); + Dbg.Assert(nodes[indexToRemove] != null, "no node at specified index"); + Dbg.Assert(nodeToRemove.Children == null || nodeToRemove.Children.Count == 0, "can't remove a node with children"); #endif - nodes.RemoveAt(indexToRemove); - --_nodeCount; + nodes.RemoveAt(indexToRemove); + --_nodeCount; #if DEBUG || ASSERTIONS_ON - Dbg.Assert(_nodeCount == this.CountNodes(), "We've lost track of the number of nodes in the tree"); + Dbg.Assert(_nodeCount == this.CountNodes(), "We've lost track of the number of nodes in the tree"); #endif + } + finally + { + _pendingProgressLock.ExitWriteLock(); + } } @@ -289,13 +298,21 @@ class PendingProgress void AddNode(ArrayList nodes, ProgressNode nodeToAdd) { - nodes.Add(nodeToAdd); - ++_nodeCount; + _pendingProgressLock.EnterWriteLock(); + try + { + nodes.Add(nodeToAdd); + ++_nodeCount; #if DEBUG || ASSERTIONS_TRACE Dbg.Assert(_nodeCount == this.CountNodes(), "We've lost track of the number of nodes in the tree"); Dbg.Assert(_nodeCount <= maxNodeCount, "Too many nodes in tree!"); #endif + } + finally + { + _pendingProgressLock.ExitWriteLock(); + } } @@ -760,21 +777,29 @@ internal override return; } - foreach (ProgressNode node in nodes) + _pendingProgressLock.EnterReadLock(); + try { - int lines = strings.Count; + foreach (ProgressNode node in nodes) + { + int lines = strings.Count; - node.Render(strings, indentation, maxWidth, rawUI); + node.Render(strings, indentation, maxWidth, rawUI); - if (node.Children != null) - { - // indent only if the rendering of node actually added lines to the strings. + if (node.Children != null) + { + // indent only if the rendering of node actually added lines to the strings. - int indentationIncrement = (strings.Count > lines) ? 2 : 0; + int indentationIncrement = (strings.Count > lines) ? 2 : 0; - RenderHelper(strings, node.Children, indentation + indentationIncrement, maxWidth, rawUI); + RenderHelper(strings, node.Children, indentation + indentationIncrement, maxWidth, rawUI); + } } } + finally + { + _pendingProgressLock.ExitReadLock(); + } } @@ -1207,8 +1232,6 @@ internal static private ArrayList _topLevelNodes = new ArrayList(); private int _nodeCount; private const int maxNodeCount = 128; + private ReaderWriterLockSlim _pendingProgressLock = new ReaderWriterLockSlim(); } } // namespace - - -