diff options
author | Thiago de Arruda <tpadilha84@gmail.com> | 2014-10-20 16:07:30 -0300 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-10-21 11:05:49 -0300 |
commit | 72f028abcb167b2ca7e2d6d770af81a18ef58a0a (patch) | |
tree | 9c6deea47af4694c049d0759b582df3426b9789f /src/nvim/eval.c | |
parent | b527ac752fd5ebcc74c06306e7009e2b98e4ee01 (diff) | |
download | rneovim-72f028abcb167b2ca7e2d6d770af81a18ef58a0a.tar.gz rneovim-72f028abcb167b2ca7e2d6d770af81a18ef58a0a.tar.bz2 rneovim-72f028abcb167b2ca7e2d6d770af81a18ef58a0a.zip |
eval: Defer execution of JobActivity autocommands
JobActivity autocommands run vimscript and must be executed on Nvim main loop.
Since the previous commit removed automatic calls to `event_push` on RStream/Job
callbacks, this adds it back, but in eval.c where job control is implemented.
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r-- | src/nvim/eval.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c8f0799d5a..3fc4104258 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -18,6 +18,8 @@ #include <stdbool.h> #include <math.h> +#include "nvim/lib/klist.h" + #include "nvim/assert.h" #include "nvim/vim.h" #include "nvim/ascii.h" @@ -86,6 +88,7 @@ #include "nvim/api/vim.h" #include "nvim/os/dl.h" #include "nvim/os/provider.h" +#include "nvim/os/event.h" #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ @@ -443,6 +446,16 @@ static dictitem_T vimvars_var; /* variable used for v: */ #define FNE_CHECK_START 2 /* find_name_end(): check name starts with valid character */ +// Memory pool for reusing JobEvent structures +typedef struct { + Job *job; + RStream *rstream; + char *type; +} JobEvent; +#define JobEventFreer(x) +KMEMPOOL_INIT(JobEventPool, JobEvent, JobEventFreer) +kmempool_t(JobEventPool) *job_event_pool = NULL; + /* * Initialize the global and v: variables. */ @@ -478,6 +491,7 @@ void eval_init(void) set_vim_var_nr(VV_HLSEARCH, 1L); set_reg_var(0); /* default for v:register is not 0 but '"' */ + job_event_pool = kmp_init(JobEventPool); } #if defined(EXITFREE) || defined(PROTO) @@ -19508,35 +19522,55 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags) return ret; } +// JobActivity autocommands will execute vimscript code, so it must be executed +// on Nvim main loop +#define push_job_event(j, r, t) \ + do { \ + JobEvent *event_data = kmp_alloc(JobEventPool, job_event_pool); \ + event_data->job = j; \ + event_data->rstream = r; \ + event_data->type = t; \ + event_push((Event) { \ + .handler = on_job_event, \ + .data = event_data \ + }); \ + } while(0) + static void on_job_stdout(RStream *rstream, void *data, bool eof) { if (!eof) { - on_job_data(rstream, data, eof, "stdout"); + push_job_event(data, rstream, "stdout"); } } static void on_job_stderr(RStream *rstream, void *data, bool eof) { if (!eof) { - on_job_data(rstream, data, eof, "stderr"); + push_job_event(data, rstream, "stderr"); } } static void on_job_exit(Job *job, void *data) { - apply_job_autocmds(job, data, "exit", NULL); - free(data); + push_job_event(data, NULL, "exit"); } -static void on_job_data(RStream *rstream, void *data, bool eof, char *type) +static void on_job_event(Event event) { - Job *job = data; - uint32_t read_count = rstream_pending(rstream); - char *str = xmalloc(read_count + 1); + JobEvent *data = event.data; + Job *job = data->job; + char *str = NULL; + + if (data->rstream) { + // Read event + size_t read_count = rstream_pending(data->rstream); + str = xmalloc(read_count + 1); - rstream_read(rstream, str, read_count); - str[read_count] = NUL; - apply_job_autocmds(job, job_data(job), type, str); + rstream_read(data->rstream, str, read_count); + str[read_count] = NUL; + } + apply_job_autocmds(job, job_data(job), data->type, str); + kmp_free(JobEventPool, job_event_pool, data); } static void apply_job_autocmds(Job *job, char *name, char *type, char *str) |