summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/channel.c9
-rw-r--r--src/testdir/test_channel.vim14
-rw-r--r--src/testdir/test_channel_pipe.py3
-rw-r--r--src/version.c2
4 files changed, 26 insertions, 2 deletions
diff --git a/src/channel.c b/src/channel.c
index 34a1fc3e0..d728c77d9 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -91,9 +91,10 @@ fd_write(sock_T fd, char *buf, size_t len)
size = MAX_NAMED_PIPE_SIZE;
else
size = (DWORD)todo;
- // If the pipe overflows while the job does not read the data, WriteFile
- // will block forever. This abandons the write.
+ // 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));
+ nwrite = 0;
if (!WriteFile(h, buf + done, size, &nwrite, &ov))
{
DWORD err = GetLastError();
@@ -104,6 +105,10 @@ fd_write(sock_T fd, char *buf, size_t len)
return -1;
FlushFileBuffers(h);
}
+ else if (nwrite == 0)
+ // WriteFile() returns TRUE but did not write anything. This causes
+ // a hang, so bail out.
+ break;
todo -= nwrite;
done += nwrite;
}
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index 2aef3e1dc..becd5484f 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -2003,6 +2003,20 @@ func Test_raw_large_data()
endtry
endfunc
+func Test_no_hang_windows()
+ if !has('job') || !has('win32')
+ return
+ endif
+
+ try
+ let job = job_start(s:python . " test_channel_pipe.py busy",
+ \ {'mode': 'raw', 'drop': 'never', 'noblock': 0})
+ call assert_fails('call ch_sendraw(job, repeat("X", 80000))', 'E631:')
+ finally
+ call job_stop(job)
+ endtry
+endfunc
+
func Test_job_exitval_and_termsig()
if !has('unix')
return
diff --git a/src/testdir/test_channel_pipe.py b/src/testdir/test_channel_pipe.py
index 810a8e303..5caffcbf9 100644
--- a/src/testdir/test_channel_pipe.py
+++ b/src/testdir/test_channel_pipe.py
@@ -18,6 +18,9 @@ if __name__ == "__main__":
print(sys.argv[1], end='')
sys.stdout.flush()
sys.exit(0)
+ elif sys.argv[1].startswith("busy"):
+ time.sleep(100)
+ sys.exit(0)
else:
print(sys.argv[1])
sys.stdout.flush()
diff --git a/src/version.c b/src/version.c
index e31b7cace..a990f2c3c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -784,6 +784,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 889,
+/**/
888,
/**/
887,