Mercurial > vim
changeset 19820:49e38e5472e6 v8.2.0466
patch 8.2.0466: not parsing messages recursively breaks the govim plugin
Commit: https://github.com/vim/vim/commit/09c569038c42dcbdaa5c9b35fc9d1afbe5072cb4
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 28 18:06:31 2020 +0100
patch 8.2.0466: not parsing messages recursively breaks the govim plugin
Problem: Not parsing messages recursively breaks the govim plugin.
Solution: When called recursively do handle messages but do not close
channels.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 28 Mar 2020 18:15:04 +0100 |
parents | b08a044fe7e7 |
children | 54157d9d75c7 |
files | src/channel.c src/version.c |
diffstat | 2 files changed, 35 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/src/channel.c +++ b/src/channel.c @@ -4428,16 +4428,14 @@ channel_parse_messages(void) int ret = FALSE; int r; ch_part_T part = PART_SOCK; - static int recursive = FALSE; + static int recursive = 0; #ifdef ELAPSED_FUNC elapsed_T start_tv; #endif // The code below may invoke callbacks, which might call us back. - // That doesn't work well, just return without doing anything. - if (recursive) - return FALSE; - recursive = TRUE; + // In a recursive call channels will not be closed. + ++recursive; ++safe_to_invoke_callback; #ifdef ELAPSED_FUNC @@ -4454,33 +4452,37 @@ channel_parse_messages(void) } while (channel != NULL) { - if (channel_can_close(channel)) - { - channel->ch_to_be_closed = (1U << PART_COUNT); - channel_close_now(channel); - // channel may have been freed, start over - channel = first_channel; - continue; - } - if (channel->ch_to_be_freed || channel->ch_killing) + if (recursive == 1) { - channel_free_contents(channel); - if (channel->ch_job != NULL) - channel->ch_job->jv_channel = NULL; - - // free the channel and then start over - channel_free_channel(channel); - channel = first_channel; - continue; + if (channel_can_close(channel)) + { + channel->ch_to_be_closed = (1U << PART_COUNT); + channel_close_now(channel); + // channel may have been freed, start over + channel = first_channel; + continue; + } + if (channel->ch_to_be_freed || channel->ch_killing) + { + channel_free_contents(channel); + if (channel->ch_job != NULL) + channel->ch_job->jv_channel = NULL; + + // free the channel and then start over + channel_free_channel(channel); + channel = first_channel; + continue; + } + if (channel->ch_refcount == 0 && !channel_still_useful(channel)) + { + // channel is no longer useful, free it + channel_free(channel); + channel = first_channel; + part = PART_SOCK; + continue; + } } - if (channel->ch_refcount == 0 && !channel_still_useful(channel)) - { - // channel is no longer useful, free it - channel_free(channel); - channel = first_channel; - part = PART_SOCK; - continue; - } + if (channel->ch_part[part].ch_fd != INVALID_FD || channel_has_readahead(channel, part)) { @@ -4521,7 +4523,7 @@ channel_parse_messages(void) } --safe_to_invoke_callback; - recursive = FALSE; + --recursive; return ret; }