mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.1.0710: when using timers may wait for job exit quite long
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)
This commit is contained in:
parent
27a472c32e
commit
c46af53410
@ -1893,3 +1893,40 @@ func Test_keep_pty_open()
|
|||||||
call assert_inrange(200, 1000, elapsed)
|
call assert_inrange(200, 1000, elapsed)
|
||||||
call job_stop(job)
|
call job_stop(job)
|
||||||
endfunc
|
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
|
||||||
|
36
src/ui.c
36
src/ui.c
@ -205,7 +205,7 @@ theend:
|
|||||||
return retval;
|
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.
|
* Wait for a timer to fire or "wait_func" to return non-zero.
|
||||||
* Returns OK when something was read.
|
* Returns OK when something was read.
|
||||||
@ -221,15 +221,18 @@ ui_wait_for_chars_or_timer(
|
|||||||
int due_time;
|
int due_time;
|
||||||
long remaining = wtime;
|
long remaining = wtime;
|
||||||
int tb_change_cnt = typebuf.tb_change_cnt;
|
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)
|
if (wtime >= 0 && wtime < 10L)
|
||||||
return wait_func(wtime, NULL, ignore_input);
|
return wait_func(wtime, NULL, ignore_input);
|
||||||
|
|
||||||
while (wtime < 0 || remaining > 0)
|
while (wtime < 0 || remaining > 0)
|
||||||
{
|
{
|
||||||
/* Trigger timers and then get the time in wtime until the next one is
|
// Trigger timers and then get the time in wtime until the next one is
|
||||||
* due. Wait up to that time. */
|
// due. Wait up to that time.
|
||||||
due_time = check_due_timer();
|
due_time = check_due_timer();
|
||||||
if (typebuf.tb_change_cnt != tb_change_cnt)
|
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))
|
if (due_time <= 0 || (wtime > 0 && due_time > remaining))
|
||||||
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))
|
if (wait_func(due_time, interrupted, ignore_input))
|
||||||
return OK;
|
return OK;
|
||||||
if (interrupted != NULL && *interrupted)
|
if ((interrupted != NULL && *interrupted)
|
||||||
/* Nothing available, but need to return so that side effects get
|
# ifdef FEAT_JOB_CHANNEL
|
||||||
* handled, such as handling a message on a 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;
|
return FAIL;
|
||||||
if (wtime > 0)
|
if (wtime > 0)
|
||||||
remaining -= due_time;
|
remaining -= due_time;
|
||||||
@ -252,7 +272,7 @@ ui_wait_for_chars_or_timer(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return non-zero if a character is available
|
* Return non-zero if a character is available.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ui_char_avail(void)
|
ui_char_avail(void)
|
||||||
|
@ -799,6 +799,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
710,
|
||||||
/**/
|
/**/
|
||||||
709,
|
709,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user