aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2021-09-28 19:12:39 +0200
committerGitHub <noreply@github.com>2021-09-28 19:12:39 +0200
commit3507d58dfb87923aa4031cbefaf1ef576a45dcaf (patch)
tree1734196f5dd366dda2306a7055cf1caac43ab97c /src
parent19a77cd5a7cbd304e57118d6a09798223b6d2dbf (diff)
parenta0ec8597e3ef01b0121af7542fc482ae8e7eeb70 (diff)
downloadrneovim-3507d58dfb87923aa4031cbefaf1ef576a45dcaf.tar.gz
rneovim-3507d58dfb87923aa4031cbefaf1ef576a45dcaf.tar.bz2
rneovim-3507d58dfb87923aa4031cbefaf1ef576a45dcaf.zip
Merge pull request #15812 from bfredl/taba
fix(runtime): make a copy of runtime_search_path when iterating
Diffstat (limited to 'src')
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/runtime.c56
2 files changed, 42 insertions, 16 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 77a161a3e1..8bdba82b67 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -2398,7 +2398,7 @@ static char_u *did_set_string_option(int opt_idx, char_u **varp, bool new_value_
didset_vimruntime = false;
}
} else if (varp == &p_rtp || varp == &p_pp) { // 'runtimepath' 'packpath'
- invalidate_search_path();
+ runtime_search_path_invalidate();
} else if (varp == &curwin->w_p_culopt
|| gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt'
if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK) {
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index 6bed22fbb0..d87f8f9803 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -21,7 +21,8 @@
# include "runtime.c.generated.h"
#endif
-static bool search_path_valid = false;
+static bool runtime_search_path_valid = false;
+static int *runtime_search_path_ref = NULL;
static RuntimeSearchPath runtime_search_path;
/// ":runtime [what] {name}"
@@ -167,7 +168,7 @@ int do_in_path(char_u *path, char_u *name, int flags, DoInRuntimepathCB callback
/// return FAIL when no file could be sourced, OK otherwise.
int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void *cookie)
{
- validate_search_path();
+ runtime_search_path_validate();
char_u *tail;
int num_files;
char_u **files;
@@ -182,9 +183,18 @@ int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void
verbose_leave();
}
- // Loop over all entries in 'runtimepath'.
- for (size_t j = 0; j < kv_size(runtime_search_path); j++) {
- SearchPathItem item = kv_A(runtime_search_path, j);
+ RuntimeSearchPath path = runtime_search_path;
+ int ref = 0;
+ if (runtime_search_path_ref == NULL) {
+ // cached path was unreferenced. keep a ref to
+ // prevent runtime_search_path() to freeing it too early
+ ref++;
+ runtime_search_path_ref = &ref;
+ }
+
+ // Loop over all entries in cached path
+ for (size_t j = 0; j < kv_size(path); j++) {
+ SearchPathItem item = kv_A(path, j);
size_t buflen = strlen(item.path);
// Skip after or non-after directories.
@@ -246,6 +256,14 @@ int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void
}
}
+ if (ref) {
+ if (runtime_search_path_ref == &ref) {
+ runtime_search_path_ref = NULL;
+ } else {
+ runtime_search_path_free(path);
+ }
+ }
+
return did_one ? OK : FAIL;
}
@@ -361,7 +379,7 @@ static bool path_is_after(char_u *buf, size_t buflen)
&& STRCMP(buf + buflen - 5, "after") == 0;
}
-RuntimeSearchPath build_runtime_search_path(void)
+RuntimeSearchPath runtime_search_path_build(void)
{
kvec_t(String) pack_entries = KV_INITIAL_VALUE;
Map(String, handle_T) pack_used = MAP_INIT;
@@ -426,21 +444,29 @@ RuntimeSearchPath build_runtime_search_path(void)
return search_path;
}
-void invalidate_search_path(void)
+void runtime_search_path_invalidate(void)
{
- search_path_valid = false;
+ runtime_search_path_valid = false;
}
-void validate_search_path(void)
+void runtime_search_path_free(RuntimeSearchPath path)
{
- if (!search_path_valid) {
- for (size_t j = 0; j < kv_size(runtime_search_path); j++) {
- SearchPathItem item = kv_A(runtime_search_path, j);
+ for (size_t j = 0; j < kv_size(path); j++) {
+ SearchPathItem item = kv_A(path, j);
xfree(item.path);
}
- kv_destroy(runtime_search_path);
- runtime_search_path = build_runtime_search_path();
- search_path_valid = true;
+ kv_destroy(path);
+}
+
+void runtime_search_path_validate(void)
+{
+ if (!runtime_search_path_valid) {
+ if (!runtime_search_path_ref) {
+ runtime_search_path_free(runtime_search_path);
+ }
+ runtime_search_path = runtime_search_path_build();
+ runtime_search_path_valid = true;
+ runtime_search_path_ref = NULL; // initially unowned
}
}