mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
commit
5e18550ddd
@ -237,15 +237,16 @@ void channel_create_event(Channel *chan, const char *ext_source)
|
||||
#endif
|
||||
}
|
||||
|
||||
void channel_incref(Channel *channel)
|
||||
void channel_incref(Channel *chan)
|
||||
{
|
||||
channel->refcount++;
|
||||
chan->refcount++;
|
||||
}
|
||||
|
||||
void channel_decref(Channel *channel)
|
||||
void channel_decref(Channel *chan)
|
||||
{
|
||||
if (!(--channel->refcount)) {
|
||||
multiqueue_put(main_loop.fast_events, free_channel_event, 1, channel);
|
||||
if (!(--chan->refcount)) {
|
||||
// delay free, so that libuv is done with the handles
|
||||
multiqueue_put(main_loop.events, free_channel_event, 1, chan);
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,18 +268,18 @@ void callback_reader_start(CallbackReader *reader)
|
||||
|
||||
static void free_channel_event(void **argv)
|
||||
{
|
||||
Channel *channel = argv[0];
|
||||
if (channel->is_rpc) {
|
||||
rpc_free(channel);
|
||||
Channel *chan = argv[0];
|
||||
if (chan->is_rpc) {
|
||||
rpc_free(chan);
|
||||
}
|
||||
|
||||
callback_reader_free(&channel->on_stdout);
|
||||
callback_reader_free(&channel->on_stderr);
|
||||
callback_free(&channel->on_exit);
|
||||
callback_reader_free(&chan->on_stdout);
|
||||
callback_reader_free(&chan->on_stderr);
|
||||
callback_free(&chan->on_exit);
|
||||
|
||||
pmap_del(uint64_t)(channels, channel->id);
|
||||
multiqueue_free(channel->events);
|
||||
xfree(channel);
|
||||
pmap_del(uint64_t)(channels, chan->id);
|
||||
multiqueue_free(chan->events);
|
||||
xfree(chan);
|
||||
}
|
||||
|
||||
static void channel_destroy_early(Channel *chan)
|
||||
@ -286,12 +287,15 @@ static void channel_destroy_early(Channel *chan)
|
||||
if ((chan->id != --next_chan_id)) {
|
||||
abort();
|
||||
}
|
||||
pmap_del(uint64_t)(channels, chan->id);
|
||||
chan->id = 0;
|
||||
|
||||
if ((--chan->refcount != 0)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
free_channel_event((void **)&chan);
|
||||
// uv will keep a reference to handles until next loop tick, so delay free
|
||||
multiqueue_put(main_loop.events, free_channel_event, 1, chan);
|
||||
}
|
||||
|
||||
|
||||
|
@ -640,6 +640,21 @@ describe('jobs', function()
|
||||
ok(string.find(err, "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set") ~= nil)
|
||||
end)
|
||||
|
||||
it('does not crash when repeatedly failing to start shell', function()
|
||||
source([[
|
||||
set shell=nosuchshell
|
||||
func! DoIt()
|
||||
call jobstart('true')
|
||||
call jobstart('true')
|
||||
endfunc
|
||||
]])
|
||||
-- The crash only triggered if both jobs are cleaned up on the same event
|
||||
-- loop tick. This is also prevented by try-block, so feed must be used.
|
||||
feed_command("call DoIt()")
|
||||
feed('<cr>') -- press RETURN
|
||||
eq(2,eval('1+1'))
|
||||
end)
|
||||
|
||||
it('jobstop() kills entire process tree #6530', function()
|
||||
command('set shell& shellcmdflag& shellquote& shellpipe& shellredir& shellxquote&')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user