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;
 }
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    466,
+/**/
     465,
 /**/
     464,