diff --git a/contrib/win32/win32compat/termio.c b/contrib/win32/win32compat/termio.c index 9ecd576790a..38b7a5c6c1b 100644 --- a/contrib/win32/win32compat/termio.c +++ b/contrib/win32/win32compat/termio.c @@ -260,6 +260,22 @@ int syncio_close(struct w32_io* pio) { debug4("syncio_close - pio:%p", pio); + + /* + * Wait for io write operation that is called by worker thread to terminate + * to avoid the write operation being terminated prematurely by CancelIoEx. + * If you see any process waiting here indefinitely - its because no one + * is draining from other end of the pipe. This is an unfortunate + * consequence that should otherwise have very little impact on practical + * scenarios. + */ + if (pio->write_details.pending) { + WaitForSingleObject(pio->write_overlapped.hEvent, INFINITE); + + /* drain queued APCs */ + SleepEx(0, TRUE); + } + CancelIoEx(WINHANDLE(pio), NULL); /* If io is pending, let worker threads exit. */ @@ -276,10 +292,10 @@ syncio_close(struct w32_io* pio) WaitForSingleObject(pio->read_overlapped.hEvent, INFINITE); } - if (pio->write_details.pending) - WaitForSingleObject(pio->write_overlapped.hEvent, INFINITE); + /* drain queued APCs */ SleepEx(0, TRUE); + /* TODO - fix this, closing Console handles is interfering with TTY/PTY rendering */ if (FILETYPE(pio) != FILE_TYPE_CHAR) CloseHandle(WINHANDLE(pio));