aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-04-13 00:35:50 +0200
committerGitHub <noreply@github.com>2018-04-13 00:35:50 +0200
commit5e18550ddde07ce90111f7bda17d86608fbb8619 (patch)
tree2e569135edc74353b1029218435aaf53b788f4ab /src
parent2cbeb7ca56503ebc203a7fae469d3ede9a5d80da (diff)
parent0865adbbc282d034849b28d70667e4415d8df829 (diff)
downloadrneovim-5e18550ddde07ce90111f7bda17d86608fbb8619.tar.gz
rneovim-5e18550ddde07ce90111f7bda17d86608fbb8619.tar.bz2
rneovim-5e18550ddde07ce90111f7bda17d86608fbb8619.zip
Merge #7813 'channels: delay free'
fix #7699
Diffstat (limited to 'src')
-rw-r--r--src/nvim/channel.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 2e32af2e9a..776e2bfa86 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -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);
}