aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 90ab471818..a3ef24f295 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -472,7 +472,7 @@ typedef struct {
#define JobEventFreer(x)
KMEMPOOL_INIT(JobEventPool, JobEvent, JobEventFreer)
static kmempool_t(JobEventPool) *job_event_pool = NULL;
-static bool defer_job_callbacks = true;
+static int disable_job_defer = 0;
/*
* Initialize the global and v: variables.
@@ -5963,11 +5963,12 @@ static bool get_dict_callback(dict_T *d, char *key, ufunc_T **result)
uint8_t *name = di->di_tv.vval.v_string;
uint8_t *n = name;
- ufunc_T *rv;
+ ufunc_T *rv = NULL;
if (*n > '9' || *n < '0') {
- n = trans_function_name(&n, false, TFN_INT|TFN_QUIET, NULL);
- rv = find_func(n);
- free(n);
+ if ((n = trans_function_name(&n, false, TFN_INT|TFN_QUIET, NULL))) {
+ rv = find_func(n);
+ free(n);
+ }
} else {
// dict function, name is already translated
rv = find_func(n);
@@ -10921,9 +10922,16 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv)
list_T *args = argvars[0].vval.v_list;
list_T *rv = list_alloc();
- // must temporarily disable job event deferring so the callbacks are
- // processed while waiting.
- defer_job_callbacks = false;
+ ui_busy_start();
+ // disable breakchecks, which could result in job callbacks being executed
+ // at unexpected places
+ disable_breakcheck++;
+ // disable job event deferring so the callbacks are processed while waiting.
+ if (!disable_job_defer++) {
+ // process any pending job events in the deferred queue, but only do this if
+ // deferred is not disabled(at the top-level `jobwait()` call)
+ event_process();
+ }
// For each item in the input list append an integer to the output list. -3
// is used to represent an invalid job id, -2 is for a interrupted job and
// -1 for jobs that were skipped or timed out.
@@ -10996,8 +11004,9 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv)
// job exits
data->status_ptr = NULL;
}
- // restore defer flag
- defer_job_callbacks = true;
+ disable_job_defer--;
+ disable_breakcheck--;
+ ui_busy_stop();
rv->lv_refcount++;
rettv->v_type = VAR_LIST;
@@ -20175,7 +20184,7 @@ static inline void push_job_event(Job *job, ufunc_T *callback,
event_push((Event) {
.handler = on_job_event,
.data = event_data
- }, defer_job_callbacks);
+ }, !disable_job_defer);
}
static void on_job_stdout(RStream *rstream, void *job, bool eof)