aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hahler <git@thequod.de>2019-11-29 09:42:58 +0100
committerJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2021-03-30 21:55:50 -0400
commit7268d49c50d01a841a32856cfc5713ae8de2fc96 (patch)
treec5aebe1c4c71e8158c44845c168b66e1c62ba1ee
parent36caafeb281bf872f11d475e594eb212636daa4d (diff)
downloadrneovim-7268d49c50d01a841a32856cfc5713ae8de2fc96.tar.gz
rneovim-7268d49c50d01a841a32856cfc5713ae8de2fc96.tar.bz2
rneovim-7268d49c50d01a841a32856cfc5713ae8de2fc96.zip
tv_dict_watcher_remove: delay freeing with busy queue
-rw-r--r--src/nvim/eval/typval.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 5b3e31b324..726619eb43 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1183,8 +1183,12 @@ bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern,
QUEUE *w = NULL;
DictWatcher *watcher = NULL;
bool matched = false;
+ bool queue_is_busy = false;
QUEUE_FOREACH(w, &dict->watchers, {
watcher = tv_dict_watcher_node_data(w);
+ if (watcher->busy) {
+ queue_is_busy = true;
+ }
if (tv_callback_equal(&watcher->callback, &callback)
&& watcher->key_pattern_len == key_pattern_len
&& memcmp(watcher->key_pattern, key_pattern, key_pattern_len) == 0) {
@@ -1197,10 +1201,10 @@ bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern,
return false;
}
- QUEUE_REMOVE(w);
- if (watcher->busy) {
+ if (queue_is_busy) {
watcher->needs_free = true;
} else {
+ QUEUE_REMOVE(w);
tv_dict_watcher_free(watcher);
}
return true;
@@ -1273,9 +1277,13 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key,
callback_call(&watcher->callback, 3, argv, &rettv);
watcher->busy = false;
tv_clear(&rettv);
- if (watcher->needs_free) {
- tv_dict_watcher_free(watcher);
- }
+ }
+ })
+ QUEUE_FOREACH(w, &dict->watchers, {
+ DictWatcher *watcher = tv_dict_watcher_node_data(w);
+ if (watcher->needs_free) {
+ QUEUE_REMOVE(w);
+ tv_dict_watcher_free(watcher);
}
})
tv_dict_unref(dict);