diff src/channel.c @ 18098:a2870e6f5b45 v8.1.2044

patch 8.1.2044: no easy way to process postponed work Commit: https://github.com/vim/vim/commit/8aeec40207b5adcd3a155277dc4f29189343b963 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Sep 15 23:02:04 2019 +0200 patch 8.1.2044: no easy way to process postponed work Problem: No easy way to process postponed work. (Paul Jolly) Solution: Add the SafeState autocommand event.
author Bram Moolenaar <Bram@vim.org>
date Sun, 15 Sep 2019 23:15:03 +0200
parents cf8e0c7e0cb9
children 0d9ec3a2821f
line wrap: on
line diff
--- a/src/channel.c
+++ b/src/channel.c
@@ -3589,10 +3589,17 @@ channel_read_json_block(
     sock_T	fd;
     int		timeout;
     chanpart_T	*chanpart = &channel->ch_part[part];
+    int		retval = FAIL;
 
     ch_log(channel, "Blocking read JSON for id %d", id);
+
+    // Not considered a safe state here, since we are processing a JSON message
+    // and parsing other messages while waiting.
+    enter_unsafe_state();
+
     if (id >= 0)
 	channel_add_block_id(chanpart, id);
+
     for (;;)
     {
 	more = channel_parse_json(channel, part);
@@ -3600,10 +3607,9 @@ channel_read_json_block(
 	// search for message "id"
 	if (channel_get_json(channel, part, id, TRUE, rettv) == OK)
 	{
-	    if (id >= 0)
-		channel_remove_block_id(chanpart, id);
 	    ch_log(channel, "Received JSON for id %d", id);
-	    return OK;
+	    retval = OK;
+	    break;
 	}
 
 	if (!more)
@@ -3659,7 +3665,11 @@ channel_read_json_block(
     }
     if (id >= 0)
 	channel_remove_block_id(chanpart, id);
-    return FAIL;
+
+    // This may trigger a SafeState autocommand.
+    leave_unsafe_state();
+
+    return retval;
 }
 
 /*
@@ -4195,9 +4205,9 @@ ch_raw_common(typval_T *argvars, typval_
     free_job_options(&opt);
 }
 
-# define KEEP_OPEN_TIME 20  /* msec */
-
-# if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
+#define KEEP_OPEN_TIME 20  /* msec */
+
+#if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
 /*
  * Add open channels to the poll struct.
  * Return the adjusted struct index.
@@ -4288,9 +4298,9 @@ channel_poll_check(int ret_in, void *fds
 
     return ret;
 }
-# endif /* UNIX && !HAVE_SELECT */
-
-# if (!defined(MSWIN) && defined(HAVE_SELECT)) || defined(PROTO)
+#endif /* UNIX && !HAVE_SELECT */
+
+#if (!defined(MSWIN) && defined(HAVE_SELECT)) || defined(PROTO)
 
 /*
  * The "fd_set" type is hidden to avoid problems with the function proto.
@@ -4381,7 +4391,7 @@ channel_select_check(int ret_in, void *r
 	if (ret > 0 && in_part->ch_fd != INVALID_FD
 					    && FD_ISSET(in_part->ch_fd, wfds))
 	{
-	    /* Clear the flag first, ch_fd may change in channel_write_input(). */
+	    // Clear the flag first, ch_fd may change in channel_write_input().
 	    FD_CLR(in_part->ch_fd, wfds);
 	    channel_write_input(channel);
 	    --ret;
@@ -4390,11 +4400,12 @@ channel_select_check(int ret_in, void *r
 
     return ret;
 }
-# endif /* !MSWIN && HAVE_SELECT */
+#endif // !MSWIN && HAVE_SELECT
 
 /*
  * Execute queued up commands.
- * Invoked from the main loop when it's safe to execute received commands.
+ * Invoked from the main loop when it's safe to execute received commands,
+ * and during a blocking wait for ch_evalexpr().
  * Return TRUE when something was done.
  */
     int