Repository: microsoft/terminal (language: cpp)

Issue:
Iconify window op causes conhost to hang
### Windows Terminal version

Commit 9eb191d5453fed890bad63952e425e1240aa8df5

### Windows build number

10.0.19044.1706

### Other Software

_No response_

### Steps to reproduce

1. Build a recent version of OpenConsole.
2. Open a bash shell.
3. Execute `printf "\e[2t"`


### Expected Behavior

The console window should be minimized.

### Actual Behavior

The window is briefly minimized and then restored again, but at that point it's no longer responding. Can't move it. Can't close it. Have to go to taskman to kill it.

When run from within the debugger, it appears to be blocking inside the [`ShowWindow`](https://github.com/microsoft/terminal/blob/799b5d4add799ac2fbf5c855b774cd7dcb957697/src/host/outputStream.cpp#L289) call, somewhere in "External Code".


Discussion / hints:
It looks like the "de-iconify" op is similarly affected. If you do something like this:

    sleep 5; printf "\e[1t"

then immediately minimize the window, it won't be restored after 5 seconds. At that point it'll be frozen and will have to be manually killed. 
what the 

If you break in `ConhostInternalGetSet::ShowWindow`, then add a breakpoint at the top of `Window::ConsoleWindowProc`, the second breakpoint isn't ever hit... That can't be right. I'd think user32 would send the console window a message, but we don't even get that?
Oh ho ho, that's it boys. 

``` 	
        [External Code]	
 	OpenConsole.exe!til::atomic_wait<unsigned int>(const std::atomic<unsigned int> & atomic, const unsigned int & current, unsigned long waitMilliseconds) Line 14	C++
 	OpenConsole.exe!til::ticket_lock::lock() Line 35	C++
 	OpenConsole.exe!CONSOLE_INFORMATION::LockConsole() Line 77	C++
 	OpenConsole.exe!LockConsole() Line 17	C++
>	OpenConsole.exe!Microsoft::Console::Interactivity::Win32::Window::ConsoleWindowProc(HWND__ * hWnd, unsigned int Message, unsigned __int64 wParam, __int64 lParam) Line 74	C++
 	OpenConsole.exe!Microsoft::Console::Interactivity::Win32::Window::s_ConsoleWindowProc(HWND__ * hWnd, unsigned int Message, unsigned __int64 wParam, __int64 lParam) Line 58	C++
 	[External Code]	
 	OpenConsole.exe!ConsoleInputThreadProcWin32(void * __formal) Line 1066	C++
 	[External Code]	
```

`OpenConsole.exe!ApiRoutines::WriteConsoleAImpl` already took the lock on the driver message thread. Then the UI thread tries to re-lock, but it can't do that


Fix patch:
diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp
index 900869af2a8..f136311a552 100644
--- a/src/host/outputStream.cpp
+++ b/src/host/outputStream.cpp
@@ -286,7 +286,14 @@ void ConhostInternalGetSet::ShowWindow(bool showOrHide)
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     const auto hwnd = gci.IsInVtIoMode() ? ServiceLocator::LocatePseudoWindow() : ServiceLocator::LocateConsoleWindow()->GetWindowHandle();
-    ::ShowWindow(hwnd, showOrHide ? SW_SHOWNOACTIVATE : SW_MINIMIZE);
+
+    // GH#13301 - When we send this ShowWindow message, if we send it to the
+    // conhost HWND, it's going to need to get processed by the window message
+    // thread before returning.
+    // However, ShowWindowAsync doesn't have this problem. It'll post the
+    // message to the window thread, then immediately return, so we don't have
+    // to worry about deadlocking.
+    ::ShowWindowAsync(hwnd, showOrHide ? SW_SHOWNOACTIVATE : SW_MINIMIZE);
 }
 
 // Routine Description:


Test patch: