From 911c40559a71d1eb20279c1d15f43b8332d1679b Mon Sep 17 00:00:00 2001 From: erw7 Date: Mon, 16 Sep 2019 14:23:45 +0900 Subject: [PATCH] win, tty: fix problem of receiving unexpected SIGWINCH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix an issue where WINDOWS_BUFFER_SIZE_EVENT occurs and unexpected SIGWINCH is received before calling uv__tty_console_resize_message_loop_thread. Refs: https://github.com/neovim/neovim/pull/10978#issuecomment-530742148 PR-URL: https://github.com/libuv/libuv/pull/2478 Reviewed-By: Bartosz Sosnowski Reviewed-By: Saúl Ibarra Corretgé (cherry picked from commit 501304225e9b6e131a36e4e0bd7deb81e7cee352) --- src/win/tty.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/win/tty.c b/src/win/tty.c index 1c1a8c6ff6c..6792e43f9cb 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -163,9 +163,15 @@ void uv_console_init(void) { 0, 0); if (uv__tty_console_handle != INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO sb_info; QueueUserWorkItem(uv__tty_console_resize_message_loop_thread, NULL, WT_EXECUTELONGFUNCTION); + uv_mutex_init(&uv__tty_console_resize_mutex); + if (GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) { + uv__tty_console_width = sb_info.dwSize.X; + uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; + } } } @@ -2349,16 +2355,35 @@ static void uv__determine_vterm_state(HANDLE handle) { } static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) { - CONSOLE_SCREEN_BUFFER_INFO sb_info; + NTSTATUS status; + ULONG_PTR conhost_pid; MSG msg; - if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) + if (pSetWinEventHook == NULL || pNtQueryInformationProcess == NULL) + return 0; + + status = pNtQueryInformationProcess(GetCurrentProcess(), + ProcessConsoleHostProcess, + &conhost_pid, + sizeof(conhost_pid), + NULL); + + if (!NT_SUCCESS(status)) { + /* We couldn't retrieve our console host process, probably because this + * is a 32-bit process running on 64-bit Windows. Fall back to receiving + * console events from the input stream only. */ return 0; + } - uv__tty_console_width = sb_info.dwSize.X; - uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; + /* Ensure the PID is a multiple of 4, which is required by SetWinEventHook */ + conhost_pid &= ~(ULONG_PTR)0x3; - if (pSetWinEventHook == NULL) + uv__tty_console_resized = CreateEvent(NULL, TRUE, FALSE, NULL); + if (uv__tty_console_resized == NULL) + return 0; + if (QueueUserWorkItem(uv__tty_console_resize_watcher_thread, + NULL, + WT_EXECUTELONGFUNCTION) == 0) return 0; if (!pSetWinEventHook(EVENT_CONSOLE_LAYOUT, @@ -2393,6 +2418,8 @@ static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook, width = sb_info.dwSize.X; height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; + uv_mutex_lock(&uv__tty_console_resize_mutex); + assert(uv__tty_console_width != -1 && uv__tty_console_height != -1); if (width != uv__tty_console_width || height != uv__tty_console_height) { uv__tty_console_width = width; uv__tty_console_height = height;