From aea079a25df1df5c94e97adf3c92ead397168e27 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 7 Jan 2018 10:16:39 +0100 Subject: channels: delay free so that libuv can cleanup handles add test for a crash this caused --- src/nvim/channel.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 2e32af2e9a..f31ba424f5 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -245,7 +245,8 @@ void channel_incref(Channel *channel) void channel_decref(Channel *channel) { if (!(--channel->refcount)) { - multiqueue_put(main_loop.fast_events, free_channel_event, 1, channel); + // delay free, so that libuv is done with the handles + multiqueue_put(main_loop.events, free_channel_event, 1, channel); } } @@ -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); } -- cgit From 0865adbbc282d034849b28d70667e4415d8df829 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 24 Mar 2018 09:49:31 +0100 Subject: channels: cleanup channel freeing code --- src/nvim/channel.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/nvim/channel.c b/src/nvim/channel.c index f31ba424f5..776e2bfa86 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -237,16 +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)) { + if (!(--chan->refcount)) { // delay free, so that libuv is done with the handles - multiqueue_put(main_loop.events, free_channel_event, 1, channel); + multiqueue_put(main_loop.events, free_channel_event, 1, chan); } } @@ -268,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) -- cgit