Mercurial > vim
diff src/channel.c @ 15539:ba876ced4f1f v8.1.0777
patch 8.1.0777: Win32: using pipes for channel does not work well
commit https://github.com/vim/vim/commit/b091f30bf38eacb31b9d8c97c82c7e0af9866301
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jan 19 14:37:00 2019 +0100
patch 8.1.0777: Win32: using pipes for channel does not work well
Problem: Win32: using pipes for channel does not work well.
Solution: Use a larger buffer and handle overlaps. (Yasuhiro Matsumoto,
closes #3782)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 19 Jan 2019 14:45:06 +0100 |
parents | 3ef31ce9d9f9 |
children | d89c5b339c2a |
line wrap: on
line diff
--- a/src/channel.c +++ b/src/channel.c @@ -80,11 +80,23 @@ fd_read(sock_T fd, char *buf, size_t len static int fd_write(sock_T fd, char *buf, size_t len) { - HANDLE h = (HANDLE)fd; - DWORD nwrite; - - if (!WriteFile(h, buf, (DWORD)len, &nwrite, NULL)) - return -1; + HANDLE h = (HANDLE)fd; + DWORD nwrite; + OVERLAPPED ov; + + // If the pipe overflows while the job does not read the data, WriteFile + // will block forever. This abandons the write. + memset(&ov, 0, sizeof(ov)); + if (!WriteFile(h, buf, (DWORD)len, &nwrite, &ov)) + { + DWORD err = GetLastError(); + + if (err != ERROR_IO_PENDING) + return -1; + if (!GetOverlappedResult(h, &ov, &nwrite, FALSE)) + return -1; + FlushFileBuffers(h); + } return (int)nwrite; } @@ -3168,20 +3180,7 @@ channel_wait(channel_T *channel, sock_T if (r && nread > 0) return CW_READY; if (r == 0) - { - DWORD err = GetLastError(); - - if (err != ERROR_BAD_PIPE && err != ERROR_BROKEN_PIPE) - return CW_ERROR; - - if (channel->ch_named_pipe) - { - DisconnectNamedPipe((HANDLE)fd); - ConnectNamedPipe((HANDLE)fd, NULL); - } - else - return CW_ERROR; - } + return CW_ERROR; /* perhaps write some buffer lines */ channel_write_any_lines(); @@ -3812,17 +3811,7 @@ channel_send( if (part == PART_SOCK) res = sock_write(fd, (char *)buf, len); else - { res = fd_write(fd, (char *)buf, len); -#ifdef WIN32 - if (channel->ch_named_pipe && res < 0) - { - DisconnectNamedPipe((HANDLE)fd); - ConnectNamedPipe((HANDLE)fd, NULL); - } -#endif - - } if (res < 0 && (errno == EWOULDBLOCK #ifdef EAGAIN || errno == EAGAIN