diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-09-15 23:02:04 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-09-15 23:02:04 +0200 |
commit | 8aeec40207b5adcd3a155277dc4f29189343b963 (patch) | |
tree | 4c62d41b6474eaddb0d2ad4c088bb6931b39b9ce /src/channel.c | |
parent | ea8dcf8346f488786023fd03ec1c013cda243040 (diff) | |
download | vim-git-8aeec40207b5adcd3a155277dc4f29189343b963.tar.gz |
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.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/src/channel.c b/src/channel.c index e4dbcf603..3792b354b 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 |