diff options
Diffstat (limited to 'src/nvim/eval.c')
| -rw-r--r-- | src/nvim/eval.c | 15 | 
1 files changed, 13 insertions, 2 deletions
| diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 9d8421ef04..4ab31985b5 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5560,8 +5560,10 @@ static int free_unref_items(int copyID)    bool did_free = false;    // Go through the list of dicts and free items without the copyID. +  // Don't free dicts that are referenced internally.    for (dict_T *dd = first_dict; dd != NULL; ) { -    if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) { +    if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) +        && !dd->internal_refcount) {        // Free the Dictionary and ordinary items it contains, but don't        // recurse into Lists and Dictionaries, they will be in the list        // of dicts or list of lists. */ @@ -5671,6 +5673,7 @@ dict_T *dict_alloc(void) FUNC_ATTR_NONNULL_RET    d->dv_scope = 0;    d->dv_refcount = 0;    d->dv_copyID = 0; +  d->internal_refcount = 0;    return d;  } @@ -10969,6 +10972,9 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv)      }    } +  // poll to ensure any pending callbacks from the last job are invoked +  event_poll(0); +    for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {      Job *job = NULL;      if (arg->li_tv.v_type != VAR_NUMBER @@ -20064,6 +20070,7 @@ static inline void common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout,      return;    } +  vopts->internal_refcount++;    vopts->dv_refcount++;  } @@ -20097,7 +20104,11 @@ static inline void free_term_job_data(TerminalJobData *data) {    if (data->on_exit) {      user_func_unref(data->on_exit);    } -  dict_unref(data->self); + +  if (data->self) { +    data->self->internal_refcount--; +    dict_unref(data->self); +  }    free(data);  } | 
