]> granicus.if.org Git - vim/commitdiff
patch 8.1.0710: when using timers may wait for job exit quite long v8.1.0710
authorBram Moolenaar <Bram@vim.org>
Wed, 9 Jan 2019 21:24:49 +0000 (22:24 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 9 Jan 2019 21:24:49 +0000 (22:24 +0100)
Problem:    When using timers may wait for job exit quite long.
Solution:   Return from ui_wait_for_chars_or_timer() when a job or channel
            needs to be handled. (Ozaki Kiichi, closes #3783)

src/testdir/test_channel.vim
src/ui.c
src/version.c

index f5ee7c086c658730ea1431567dc81565025c752c..8f4fb0fdcd9517cde5a2b6de1f903535ff212e2d 100644 (file)
@@ -1893,3 +1893,40 @@ func Test_keep_pty_open()
   call assert_inrange(200, 1000, elapsed)
   call job_stop(job)
 endfunc
+
+func Test_job_start_in_timer()
+  if !has('job') || !has('timers')
+    return
+  endif
+
+  func OutCb(chan, msg)
+  endfunc
+
+  func ExitCb(job, status)
+    let g:val = 1
+    call Resume()
+  endfunc
+
+  func TimerCb(timer)
+    if has('win32')
+      let cmd = ['cmd', '/c', 'echo.']
+    else
+      let cmd = ['echo']
+    endif
+    let g:job = job_start(cmd, {'out_cb': 'OutCb', 'exit_cb': 'ExitCb'})
+    call substitute(repeat('a', 100000), '.', '', 'g')
+  endfunc
+
+  " We should be interrupted before 'updatetime' elapsed.
+  let g:val = 0
+  call timer_start(1, 'TimerCb')
+  let elapsed = Standby(&ut)
+  call assert_inrange(1, &ut / 2, elapsed)
+  call job_stop(g:job)
+
+  delfunc OutCb
+  delfunc ExitCb
+  delfunc TimerCb
+  unlet! g:val
+  unlet! g:job
+endfunc
index d341448e3b2d23b5d6fecca51d532847204f404f..a392d71e4b567e46128288a22e71f5cf728aa58d 100644 (file)
--- a/src/ui.c
+++ b/src/ui.c
@@ -205,7 +205,7 @@ theend:
     return retval;
 }
 
-#if defined(FEAT_TIMERS) || defined(PROT)
+#if defined(FEAT_TIMERS) || defined(PROTO)
 /*
  * Wait for a timer to fire or "wait_func" to return non-zero.
  * Returns OK when something was read.
@@ -221,15 +221,18 @@ ui_wait_for_chars_or_timer(
     int            due_time;
     long    remaining = wtime;
     int            tb_change_cnt = typebuf.tb_change_cnt;
+# ifdef FEAT_JOB_CHANNEL
+    int            brief_wait = TRUE;
+# endif
 
-    /* When waiting very briefly don't trigger timers. */
+    // When waiting very briefly don't trigger timers.
     if (wtime >= 0 && wtime < 10L)
        return wait_func(wtime, NULL, ignore_input);
 
     while (wtime < 0 || remaining > 0)
     {
-       /* Trigger timers and then get the time in wtime until the next one is
-        * due.  Wait up to that time. */
+       // Trigger timers and then get the time in wtime until the next one is
+       // due.  Wait up to that time.
        due_time = check_due_timer();
        if (typebuf.tb_change_cnt != tb_change_cnt)
        {
@@ -238,11 +241,28 @@ ui_wait_for_chars_or_timer(
        }
        if (due_time <= 0 || (wtime > 0 && due_time > remaining))
            due_time = remaining;
+# ifdef FEAT_JOB_CHANNEL
+       if ((due_time < 0 || due_time > 10L)
+#  ifdef FEAT_GUI
+               && !gui.in_use
+#  endif
+               && (has_pending_job() || channel_any_readahead()))
+       {
+           // There is a pending job or channel, should return soon in order
+           // to handle them ASAP.  Do check for input briefly.
+           due_time = 10L;
+           brief_wait = TRUE;
+       }
+# endif
        if (wait_func(due_time, interrupted, ignore_input))
            return OK;
-       if (interrupted != NULL && *interrupted)
-           /* Nothing available, but need to return so that side effects get
-            * handled, such as handling a message on a channel. */
+       if ((interrupted != NULL && *interrupted)
+# ifdef FEAT_JOB_CHANNEL
+               || brief_wait
+# endif
+               )
+           // Nothing available, but need to return so that side effects get
+           // handled, such as handling a message on a channel.
            return FAIL;
        if (wtime > 0)
            remaining -= due_time;
@@ -252,7 +272,7 @@ ui_wait_for_chars_or_timer(
 #endif
 
 /*
- * return non-zero if a character is available
+ * Return non-zero if a character is available.
  */
     int
 ui_char_avail(void)
index e1ea65e85797f9ae7c7c0a6ee5b11e143e1f1d40..f0e4450da489c64ed1e3814505af912f09be16b9 100644 (file)
@@ -799,6 +799,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    710,
 /**/
     709,
 /**/