Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Template for new versions:
## Fixes
- Fixed ``scriptmanager.getModStatePath()`` causing scripts to crash when called
- `prospect`: don't warn about a missing magma sea in the pre-embark estimate when the world was generated without one
- Core: Windows console will no longer hang on close (on some builds of Windows)

## Misc Improvements
- `overlay`: errors raised by a bad C function result count or corrupted Lua call stack are now reported as Lua errors instead of crashing the game
Expand Down
20 changes: 17 additions & 3 deletions library/Console-windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ namespace DFHack
rawmode = 0;
console_in = 0;
console_out = 0;
exit_event = 0;
ConsoleWindow = 0;
default_attributes = 0;
state = con_unclaimed;
Expand Down Expand Up @@ -281,16 +282,21 @@ namespace DFHack
inf.dwCursorPosition.X = (SHORT)plen;
SetConsoleCursorPosition(console_out, inf.dwCursorPosition);

// exit_event comes first so shutdown wins if input is also
// pending. The console input handle is signaled whenever its
// input queue is non-empty, so the read below cannot block.
const HANDLE wait_handles[] = { exit_event, console_in };
while (1)
{
INPUT_RECORD rec;
DWORD count;
lock->unlock();
if (ReadConsoleInputA(console_in, &rec, 1, &count) == 0) {
lock->lock();
DWORD wait_result = WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE);
lock->lock();
if (wait_result != WAIT_OBJECT_0 + 1
|| ReadConsoleInputA(console_in, &rec, 1, &count) == 0) {
return Console::SHUTDOWN;
}
lock->lock();
if (rec.EventType != KEY_EVENT || !rec.Event.KeyEvent.bKeyDown)
continue;
switch (rec.Event.KeyEvent.wVirtualKeyCode)
Expand Down Expand Up @@ -396,6 +402,7 @@ namespace DFHack
int rawmode;
HANDLE console_in;
HANDLE console_out;
HANDLE exit_event;
HWND ConsoleWindow;
HWND MainWindow;
WORD default_attributes;
Expand Down Expand Up @@ -479,6 +486,9 @@ bool Console::init(bool)
d->console_owned = AllocConsole() != FALSE;
d->ConsoleWindow = GetConsoleWindow();
wlock = new std::recursive_mutex();
d->exit_event = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!d->exit_event)
return false;
if (d->console_owned)
{
HMENU hm = GetSystemMenu(d->ConsoleWindow,false);
Expand Down Expand Up @@ -537,6 +547,10 @@ bool Console::shutdown(void)
{
assert(inited);
std::lock_guard<std::recursive_mutex> lock{*wlock};
// Wake any thread waiting on console input so it leaves prompt_loop
// before we detach or reconfigure the console below.
if (d->exit_event)
SetEvent(d->exit_event);
if (d->console_owned)
{
FreeConsole();
Expand Down
Loading