summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-01-09 22:24:49 +0100
committerBram Moolenaar <Bram@vim.org>2019-01-09 22:24:49 +0100
commitc46af534102c65b43912311d67f55f5049e5ef7a (patch)
treefe6c4a5e5a9bec3d2760a47534ef3f4427184e63
parent27a472c32ed5b5298bca50864570a4a71ec1d204 (diff)
downloadvim-git-c46af534102c65b43912311d67f55f5049e5ef7a.tar.gz
patch 8.1.0710: when using timers may wait for job exit quite longv8.1.0710
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)
-rw-r--r--src/testdir/test_channel.vim37
-rw-r--r--src/ui.c36
-rw-r--r--src/version.c2
3 files changed, 67 insertions, 8 deletions
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index f5ee7c086..8f4fb0fdc 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -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
diff --git a/src/ui.c b/src/ui.c
index d341448e3..a392d71e4 100644
--- 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)
diff --git a/src/version.c b/src/version.c
index e1ea65e85..f0e4450da 100644
--- a/src/version.c
+++ b/src/version.c
@@ -800,6 +800,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 710,
+/**/
709,
/**/
708,