From 3376247826050a81d7230d65fa2f50a9145c6498 Mon Sep 17 00:00:00 2001 From: ORelio Date: Sun, 10 May 2015 18:57:33 +0200 Subject: [PATCH] Fix concurrency in ConsoleIO Fix concurrency issues by using proper locks --- MinecraftClient/ConsoleIO.cs | 77 ++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/MinecraftClient/ConsoleIO.cs b/MinecraftClient/ConsoleIO.cs index 463d309e..9f6f18ab 100644 --- a/MinecraftClient/ConsoleIO.cs +++ b/MinecraftClient/ConsoleIO.cs @@ -14,16 +14,30 @@ namespace MinecraftClient public static class ConsoleIO { - public static void Reset() { if (reading) { ClearLineAndBuffer(); reading = false; Console.Write("\b \b"); } } - public static void SetAutoCompleteEngine(IAutoComplete engine) { autocomplete_engine = engine; } public static bool basicIO = false; private static IAutoComplete autocomplete_engine; private static LinkedList previous = new LinkedList(); private static string buffer = ""; private static string buffer2 = ""; private static bool reading = false; - private static bool reading_lock = false; - private static bool writing_lock = false; + private static object io_lock = new object(); + + /// + /// Reset the IO mechanism & clear all buffers + /// + + public static void Reset() + { + lock (io_lock) + { + if (reading) + { + ClearLineAndBuffer(); + reading = false; + Console.Write("\b \b"); + } + } + } /// /// Read a password from the standard input @@ -82,16 +96,20 @@ namespace MinecraftClient { if (basicIO) { return Console.ReadLine(); } ConsoleKeyInfo k = new ConsoleKeyInfo(); - Console.Write('>'); - reading = true; - buffer = ""; - buffer2 = ""; + + lock (io_lock) + { + Console.Write('>'); + reading = true; + buffer = ""; + buffer2 = ""; + } while (k.Key != ConsoleKey.Enter) { k = Console.ReadKey(true); - while (writing_lock) { } - reading_lock = true; + lock (io_lock) + { if (k.Key == ConsoleKey.V && k.Modifiers == ConsoleModifiers.Control) { string clip = ReadClipboard(); @@ -173,13 +191,16 @@ namespace MinecraftClient AddChar(k.KeyChar); break; } + } } - reading_lock = false; } - while (writing_lock) { } - reading = false; - previous.AddLast(buffer + buffer2); - return buffer + buffer2; + + lock (io_lock) + { + reading = false; + previous.AddLast(buffer + buffer2); + return buffer + buffer2; + } } /// @@ -188,9 +209,10 @@ namespace MinecraftClient public static void Write(string text) { - if (basicIO) { Console.Write(text); return; } - while (reading_lock) { } - writing_lock = true; + if (!basicIO) + { + lock (io_lock) + { if (reading) { try @@ -221,12 +243,13 @@ namespace MinecraftClient { //Console resized: Try again Console.Write('\n'); - writing_lock = false; Write(text); } } else Console.Write(text); - writing_lock = false; + } + } + else Console.Write(text); } /// @@ -289,7 +312,7 @@ namespace MinecraftClient case 'd': Console.ForegroundColor = ConsoleColor.Magenta; break; case 'e': Console.ForegroundColor = ConsoleColor.Yellow; break; case 'f': Console.ForegroundColor = ConsoleColor.White; break; - case 'r': Console.ForegroundColor = ConsoleColor.White; break; + case 'r': Console.ForegroundColor = ConsoleColor.Gray; break; } if (subs[i].Length > 1) @@ -387,6 +410,18 @@ namespace MinecraftClient return clipdata; } #endregion + + #region AutoComplete API + /// + /// Set an auto-completion engine for TAB autocompletion + /// + /// Engine implementing the IAutoComplete interface + + public static void SetAutoCompleteEngine(IAutoComplete engine) + { + autocomplete_engine = engine; + } + #endregion } ///