changeset 8736:06bf71f13eb7 v7.4.1657

commit https://github.com/vim/vim/commit/8fdd7210479f0c486822ad8934087b4bfd8a4765 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Mar 26 19:41:48 2016 +0100 patch 7.4.1657 Problem: On Unix in a terminal: channel messages are not handled right away. (Jackson Alves de Aquino) Solution: Break the loop for timers when something was received.
author Christian Brabandt <cb@256bit.org>
date Sat, 26 Mar 2016 19:45:04 +0100
parents d3f32626fabe
children b3a380af91fb
files src/os_unix.c src/version.c
diffstat 2 files changed, 28 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -176,11 +176,11 @@ typedef int waitstatus;
 static pid_t wait4pid(pid_t, waitstatus *);
 
 static int  WaitForChar(long);
-static int  WaitForCharOrMouse(long);
+static int  WaitForCharOrMouse(long, int *break_loop);
 #if defined(__BEOS__) || defined(VMS)
-int  RealWaitForChar(int, long, int *);
+int  RealWaitForChar(int, long, int *, int *break_loop);
 #else
-static int  RealWaitForChar(int, long, int *);
+static int  RealWaitForChar(int, long, int *, int *break_loop);
 #endif
 
 #ifdef FEAT_XCLIPBOARD
@@ -366,7 +366,7 @@ mch_write(char_u *s, int len)
 {
     ignored = (int)write(1, (char *)s, len);
     if (p_wd)		/* Unix is too fast, slow down a bit more */
-	RealWaitForChar(read_cmd_fd, p_wd, NULL);
+	RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL);
 }
 
 /*
@@ -4762,7 +4762,7 @@ mch_call_shell(
 		     * to some terminal (vt52?).
 		     */
 		    ++noread_cnt;
-		    while (RealWaitForChar(fromshell_fd, 10L, NULL))
+		    while (RealWaitForChar(fromshell_fd, 10L, NULL, NULL))
 		    {
 			len = read_eintr(fromshell_fd, buffer
 # ifdef FEAT_MBYTE
@@ -5343,7 +5343,7 @@ mch_clear_job(job_T *job)
     void
 mch_breakcheck(void)
 {
-    if (curr_tmode == TMODE_RAW && RealWaitForChar(read_cmd_fd, 0L, NULL))
+    if (curr_tmode == TMODE_RAW && RealWaitForChar(read_cmd_fd, 0L, NULL, NULL))
 	fill_input_buf(FALSE);
 }
 
@@ -5360,10 +5360,11 @@ WaitForChar(long msec)
 #ifdef FEAT_TIMERS
     long    due_time;
     long    remaining = msec;
+    int	    break_loop = FALSE;
 
     /* When waiting very briefly don't trigger timers. */
     if (msec >= 0 && msec < 10L)
-	return WaitForCharOrMouse(msec);
+	return WaitForCharOrMouse(msec, NULL);
 
     while (msec < 0 || remaining > 0)
     {
@@ -5372,14 +5373,18 @@ WaitForChar(long msec)
 	due_time = check_due_timer();
 	if (due_time <= 0 || (msec > 0 && due_time > remaining))
 	    due_time = remaining;
-	if (WaitForCharOrMouse(due_time))
+	if (WaitForCharOrMouse(due_time, &break_loop))
 	    return TRUE;
+	if (break_loop)
+	    /* Nothing available, but need to return so that side effects get
+	     * handled, such as handling a message on a channel. */
+	    return FALSE;
 	if (msec > 0)
 	    remaining -= due_time;
     }
     return FALSE;
 #else
-    return WaitForCharOrMouse(msec);
+    return WaitForCharOrMouse(msec, NULL);
 #endif
 }
 
@@ -5390,7 +5395,7 @@ WaitForChar(long msec)
  * When a GUI is being used, this will never get called -- webb
  */
     static int
-WaitForCharOrMouse(long msec)
+WaitForCharOrMouse(long msec, int *break_loop)
 {
 #ifdef FEAT_MOUSE_GPM
     int		gpm_process_wanted;
@@ -5436,9 +5441,10 @@ WaitForCharOrMouse(long msec)
 # endif
 # ifdef FEAT_MOUSE_GPM
 	gpm_process_wanted = 0;
-	avail = RealWaitForChar(read_cmd_fd, msec, &gpm_process_wanted);
+	avail = RealWaitForChar(read_cmd_fd, msec,
+					     &gpm_process_wanted, break_loop);
 # else
-	avail = RealWaitForChar(read_cmd_fd, msec, NULL);
+	avail = RealWaitForChar(read_cmd_fd, msec, NULL, break_loop);
 # endif
 	if (!avail)
 	{
@@ -5457,10 +5463,11 @@ WaitForCharOrMouse(long msec)
 # ifdef FEAT_XCLIPBOARD
 	   || (!avail && rest != 0)
 # endif
-	  );
+	  )
+	;
 
 #else
-    avail = RealWaitForChar(read_cmd_fd, msec, NULL);
+    avail = RealWaitForChar(read_cmd_fd, msec, NULL, &break_loop);
 #endif
     return avail;
 }
@@ -5479,7 +5486,7 @@ WaitForCharOrMouse(long msec)
 #else
     static int
 #endif
-RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED)
+RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *break_loop)
 {
     int		ret;
     int		result;
@@ -5592,6 +5599,8 @@ RealWaitForChar(int fd, long msec, int *
 	ret = poll(fds, nfd, towait);
 
 	result = ret > 0 && (fds[0].revents & POLLIN);
+	if (break_loop != NULL && ret > 0)
+	    *break_loop = TRUE;
 
 # ifdef FEAT_MZSCHEME
 	if (ret == 0 && mzquantum_used)
@@ -5723,6 +5732,8 @@ select_eintr:
 	result = ret > 0 && FD_ISSET(fd, &rfds);
 	if (result)
 	    --ret;
+	if (break_loop != NULL && ret > 0)
+	    *break_loop = TRUE;
 
 # ifdef EINTR
 	if (ret == -1 && errno == EINTR)
--- a/src/version.c
+++ b/src/version.c
@@ -749,6 +749,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1657,
+/**/
     1656,
 /**/
     1655,