forked from aniani/vim
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)
This commit is contained in:
@@ -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;
|
||||
HANDLE h = (HANDLE)fd;
|
||||
DWORD nwrite;
|
||||
OVERLAPPED ov;
|
||||
|
||||
if (!WriteFile(h, buf, (DWORD)len, &nwrite, NULL))
|
||||
return -1;
|
||||
// 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 fd, int timeout)
|
||||
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
|
||||
|
Reference in New Issue
Block a user