0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.1.0350: Vim may block on ch_sendraw()

Problem:    Vim may block on ch_sendraw() when the job is sending data back to
            Vim, which isn't read yet. (Nate Bosch)
Solution:   Add the "noblock" option to job_start(). (closes #2548)
This commit is contained in:
Bram Moolenaar
2018-09-06 16:27:24 +02:00
parent ed5a9d6612
commit 0b1468884a
5 changed files with 62 additions and 2 deletions

View File

@@ -47,8 +47,11 @@ endfunc
func Ch_communicate(port)
" Avoid dropping messages, since we don't use a callback here.
let s:chopt.drop = 'never'
" Also add the noblock flag to try it out.
let s:chopt.noblock = 1
let handle = ch_open('localhost:' . a:port, s:chopt)
unlet s:chopt.drop
unlet s:chopt.noblock
if ch_status(handle) == "fail"
call assert_report("Can't open channel")
return
@@ -451,8 +454,9 @@ func Test_raw_pipe()
call ch_log('Test_raw_pipe()')
" Add a dummy close callback to avoid that messages are dropped when calling
" ch_canread().
" Also test the non-blocking option.
let job = job_start(s:python . " test_channel_pipe.py",
\ {'mode': 'raw', 'drop': 'never'})
\ {'mode': 'raw', 'drop': 'never', 'noblock': 1})
call assert_equal(v:t_job, type(job))
call assert_equal("run", job_status(job))
@@ -1350,6 +1354,34 @@ endfunc
""""""""""
function ExitCbWipe(job, status)
exe g:wipe_buf 'bw!'
endfunction
" This caused a crash, because messages were handled while peeking for a
" character.
func Test_exit_cb_wipes_buf()
if !has('timers')
return
endif
set cursorline lazyredraw
call test_override('redraw_flag', 1)
new
let g:wipe_buf = bufnr('')
let job = job_start(['true'], {'exit_cb': 'ExitCbWipe'})
let timer = timer_start(300, {-> feedkeys("\<Esc>", 'nt')}, {'repeat': 5})
call feedkeys(repeat('g', 1000) . 'o', 'ntx!')
call WaitForAssert({-> assert_equal("dead", job_status(job))})
call timer_stop(timer)
set nocursorline nolazyredraw
unlet g:wipe_buf
call test_override('ALL', 0)
endfunc
""""""""""
let g:Ch_unletResponse = ''
func s:UnletHandler(handle, msg)
let g:Ch_unletResponse = a:msg