mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
jobwait(): fix race if job exits before waiting on it
Problem: If a job exits while waiting on another job, the on_exit handler is queued but f_jobwait() skips it. Solution: Always do process_wait(), so that handlers are run during f_jobwait(). fix #8302 Test case: $ BUSTED_ARGS="--repeat=2000 --no-keep-going" TEST_FILE=test/functional/core/job_spec.lua TEST_FILTER=waiting make functionaltest Failure example (macOS CI): FAILED test/functional/core/job_spec.lua: jobs jobwait will run callbacks while waiting test/functional/core/job_spec.lua:606: Expected objects to be the same. Passed in: (table: 0x1be77c80) { [1] = 'notification' [2] = 'wait' *[3] = { *[1] = 3 } } Expected: (table: 0x1be77d10) { [1] = 'notification' [2] = 'wait' *[3] = { *[1] = 4 } } stack traceback: test/functional/core/job_spec.lua:606: in function <test/functional/core/job_spec.lua:583
This commit is contained in:
parent
a00eb23c27
commit
58318af718
@ -5411,7 +5411,8 @@ jobstop({id}) *jobstop()*
|
||||
See |job-control|.
|
||||
|
||||
jobwait({ids}[, {timeout}]) *jobwait()*
|
||||
Wait for a set of jobs to complete.
|
||||
Wait for a set of jobs and their |on_exit| handlers to
|
||||
complete.
|
||||
|
||||
{ids} is a list of |job-id|s to wait for.
|
||||
{timeout} is the maximum waiting time in milliseconds, -1
|
||||
@ -5427,10 +5428,10 @@ jobwait({ids}[, {timeout}]) *jobwait()*
|
||||
Returns a list of len({ids}) integers, where each integer is
|
||||
the wait-result of the corresponding job. Each wait-result is
|
||||
one of the following:
|
||||
* Exit-code, if the job exited
|
||||
* -1 if the timeout was exceeded
|
||||
* -2 if the job was interrupted
|
||||
* -3 if the |job-id| is invalid
|
||||
Exit-code, if the job exited
|
||||
-1 if the timeout was exceeded
|
||||
-2 if the job was interrupted (by |CTRL-C|)
|
||||
-3 if the job-id is invalid
|
||||
|
||||
join({list} [, {sep}]) *join()*
|
||||
Join the items in {list} together into one String.
|
||||
|
@ -12487,7 +12487,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
}
|
||||
|
||||
// if the job already exited, but wasn't freed yet
|
||||
if (jobs[i] == NULL || jobs[i]->stream.proc.status >= 0) {
|
||||
if (jobs[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -607,7 +607,6 @@ describe('jobs', function()
|
||||
\ ])
|
||||
call rpcnotify(g:channel, 'wait', sort(g:jobs), sort(g:exits))
|
||||
]])
|
||||
assert:set_parameter('TableFormatLevel', 1000000)
|
||||
eq({'notification', 'wait',
|
||||
{{3,4,5,6}, {3,4,5,6}}}, next_msg())
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user