diff --git a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs index f929e80ee..71f67d6f8 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs @@ -5,7 +5,9 @@ namespace Terminal.Gui; internal abstract class AnsiResponseParserBase : IAnsiResponseParser { - object lockExpectedResponses = new object(); + protected object lockExpectedResponses = new object(); + + protected object lockState = new object (); /// /// Responses we are expecting to come in. /// @@ -85,6 +87,19 @@ internal abstract class AnsiResponseParserBase : IAnsiResponseParser Action appendOutput, int inputLength ) + { + lock (lockState) + { + ProcessInputBaseImpl (getCharAtIndex, getObjectAtIndex, appendOutput, inputLength); + } + } + + private void ProcessInputBaseImpl ( + Func getCharAtIndex, + Func getObjectAtIndex, + Action appendOutput, + int inputLength + ) { var index = 0; // Tracks position in the input string @@ -334,12 +349,17 @@ internal class AnsiResponseParser : AnsiResponseParserBase public IEnumerable> Release () { - foreach (Tuple h in HeldToEnumerable()) + // Lock in case Release is called from different Thread from parse + lock (lockState) { - yield return h; + foreach (Tuple h in HeldToEnumerable()) + { + yield return h; + } + + ResetState (); } - ResetState (); } private IEnumerable> HeldToEnumerable () @@ -356,13 +376,16 @@ internal class AnsiResponseParser : AnsiResponseParserBase /// public void ExpectResponseT (string terminator, Action>> response, bool persistent) { - if (persistent) + lock (lockExpectedResponses) { - persistentExpectations.Add (new (terminator, (h) => response.Invoke (HeldToEnumerable ()))); - } - else - { - expectedResponses.Add (new (terminator, (h) => response.Invoke (HeldToEnumerable ()))); + if (persistent) + { + persistentExpectations.Add (new (terminator, (h) => response.Invoke (HeldToEnumerable ()))); + } + else + { + expectedResponses.Add (new (terminator, (h) => response.Invoke (HeldToEnumerable ()))); + } } } @@ -405,10 +428,13 @@ internal class AnsiResponseParser : AnsiResponseParserBase public string Release () { - var output = heldContent.HeldToString (); - ResetState (); + lock (lockState) + { + var output = heldContent.HeldToString (); + ResetState (); - return output; + return output; + } } ///