summaryrefslogtreecommitdiffstats
path: root/src/channel.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-09-15 23:02:04 +0200
committerBram Moolenaar <Bram@vim.org>2019-09-15 23:02:04 +0200
commit8aeec40207b5adcd3a155277dc4f29189343b963 (patch)
tree4c62d41b6474eaddb0d2ad4c088bb6931b39b9ce /src/channel.c
parentea8dcf8346f488786023fd03ec1c013cda243040 (diff)
patch 8.1.2044: no easy way to process postponed workv8.1.2044
Problem: No easy way to process postponed work. (Paul Jolly) Solution: Add the SafeState autocommand event.
Diffstat (limited to 'src/channel.c')
-rw-r--r--src/channel.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/src/channel.c b/src/channel.c
index e4dbcf6039..3792b354b7 100644
--- 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_T *rettv, int eval)
free_job_options(&opt);
}
-# define KEEP_OPEN_TIME 20 /* msec */
+#define KEEP_OPEN_TIME 20 /* msec */
-# if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
+#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_in)
return ret;
}
-# endif /* UNIX && !HAVE_SELECT */
+#endif /* UNIX && !HAVE_SELECT */
-# if (!defined(MSWIN) && defined(HAVE_SELECT)) || defined(PROTO)
+#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 *rfds_in, void *wfds_in)
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 *rfds_in, void *wfds_in)
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