comparison 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
comparison
equal deleted inserted replaced
15538:0ceb89cda5c2 15539:ba876ced4f1f
78 } 78 }
79 79
80 static int 80 static int
81 fd_write(sock_T fd, char *buf, size_t len) 81 fd_write(sock_T fd, char *buf, size_t len)
82 { 82 {
83 HANDLE h = (HANDLE)fd; 83 HANDLE h = (HANDLE)fd;
84 DWORD nwrite; 84 DWORD nwrite;
85 85 OVERLAPPED ov;
86 if (!WriteFile(h, buf, (DWORD)len, &nwrite, NULL)) 86
87 return -1; 87 // If the pipe overflows while the job does not read the data, WriteFile
88 // will block forever. This abandons the write.
89 memset(&ov, 0, sizeof(ov));
90 if (!WriteFile(h, buf, (DWORD)len, &nwrite, &ov))
91 {
92 DWORD err = GetLastError();
93
94 if (err != ERROR_IO_PENDING)
95 return -1;
96 if (!GetOverlappedResult(h, &ov, &nwrite, FALSE))
97 return -1;
98 FlushFileBuffers(h);
99 }
88 return (int)nwrite; 100 return (int)nwrite;
89 } 101 }
90 102
91 static void 103 static void
92 fd_close(sock_T fd) 104 fd_close(sock_T fd)
3166 int r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL); 3178 int r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL);
3167 3179
3168 if (r && nread > 0) 3180 if (r && nread > 0)
3169 return CW_READY; 3181 return CW_READY;
3170 if (r == 0) 3182 if (r == 0)
3171 { 3183 return CW_ERROR;
3172 DWORD err = GetLastError();
3173
3174 if (err != ERROR_BAD_PIPE && err != ERROR_BROKEN_PIPE)
3175 return CW_ERROR;
3176
3177 if (channel->ch_named_pipe)
3178 {
3179 DisconnectNamedPipe((HANDLE)fd);
3180 ConnectNamedPipe((HANDLE)fd, NULL);
3181 }
3182 else
3183 return CW_ERROR;
3184 }
3185 3184
3186 /* perhaps write some buffer lines */ 3185 /* perhaps write some buffer lines */
3187 channel_write_any_lines(); 3186 channel_write_any_lines();
3188 3187
3189 sleep_time = deadline - GetTickCount(); 3188 sleep_time = deadline - GetTickCount();
3810 } 3809 }
3811 3810
3812 if (part == PART_SOCK) 3811 if (part == PART_SOCK)
3813 res = sock_write(fd, (char *)buf, len); 3812 res = sock_write(fd, (char *)buf, len);
3814 else 3813 else
3815 {
3816 res = fd_write(fd, (char *)buf, len); 3814 res = fd_write(fd, (char *)buf, len);
3817 #ifdef WIN32
3818 if (channel->ch_named_pipe && res < 0)
3819 {
3820 DisconnectNamedPipe((HANDLE)fd);
3821 ConnectNamedPipe((HANDLE)fd, NULL);
3822 }
3823 #endif
3824
3825 }
3826 if (res < 0 && (errno == EWOULDBLOCK 3815 if (res < 0 && (errno == EWOULDBLOCK
3827 #ifdef EAGAIN 3816 #ifdef EAGAIN
3828 || errno == EAGAIN 3817 || errno == EAGAIN
3829 #endif 3818 #endif
3830 )) 3819 ))