Skip to content

Fix Console methods being split across threads #1622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions source/Cosmos.System2_Plugs/System/ConsoleImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public static class ConsoleImpl
private static ConsoleColor mForeground = ConsoleColor.White;
private static ConsoleColor mBackground = ConsoleColor.Black;
private static Encoding ConsoleInputEncoding = Encoding.ASCII;
private static Encoding ConsoleOutputEncoding = Encoding.ASCII;
private static Encoding ConsoleOutputEncoding = Encoding.ASCII;
private static Core.Processing.Mutex mConsoleGateRead = new Core.Processing.Mutex();
private static Core.Processing.Mutex mConsoleGateWrite = new Core.Processing.Mutex();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please specify Cosmos.Core.Processing with an using rather than this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. will fix in a moment


private static readonly Cosmos.System.Console mFallbackConsole = new Cosmos.System.Console(null);

Expand Down Expand Up @@ -429,17 +431,20 @@ public static ConsoleKeyInfo ReadKey(bool intercept)
bool xControl = (key.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control;

return new ConsoleKeyInfo(key.KeyChar, key.Key.ToConsoleKey(), xShift, xAlt, xControl);
}

}

private static List<char> chars = new List<char>(32);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why move chars outside the ReadLine function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because if we put them into the function, every thread would have to access its own instance of characters and this would just waste memory and cause errors when threads that don't require "keyboard read" are forced to add to that list(that for them doesn't exist) a character.

public static String ReadLine()
{
if (mConsoleGateRead != null)
mConsoleGateRead.Lock();
chars = new List<char>(32);
var xConsole = GetConsole();
if (xConsole == null)
{
// for now:
return null;
}
List<char> chars = new List<char>(32);
KeyEvent current;
int currentCount = 0;

Expand Down Expand Up @@ -529,6 +534,8 @@ public static String ReadLine()
WriteLine();

char[] final = chars.ToArray();
if (mConsoleGateRead != null)
mConsoleGateRead.Unlock();
return new string(final);
}

Expand Down Expand Up @@ -601,17 +608,21 @@ public static void Write(bool aBool)
/* Correct behaviour printing null should not throw NRE or do nothing but should print an empty string */
public static void Write(object value) => Write((value ?? String.Empty));

private static Cosmos.System.Console xConsole = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


public static void Write(string aText)
{
var xConsole = GetConsole();
if (xConsole == null)
{
// for now:
return;
if (mConsoleGateWrite != null)
{
mConsoleGateWrite.Lock();
}

byte[] aTextEncoded = ConsoleOutputEncoding.GetBytes(aText);
GetConsole().Write(aTextEncoded);
//if there's some process queued, we just set the first as the main and queue the other ones
if (mConsoleGateWrite != null)
{
mConsoleGateWrite.Unlock();
}
}

public static void Write(uint aInt) => Write(aInt.ToString());
Expand Down