vendor/libgit2/src/mwindow.c in rugged-0.24.0 vs vendor/libgit2/src/mwindow.c in rugged-0.24.5

- old
+ new

@@ -31,29 +31,24 @@ static git_mwindow_ctl mem_ctl; /* Global list of mwindow files, to open packs once across repos */ git_strmap *git__pack_cache = NULL; -/** - * Run under mwindow lock - */ -int git_mwindow_files_init(void) +static void git_mwindow_files_free(void) { - if (git__pack_cache) - return 0; + git_strmap *tmp = git__pack_cache; - git__on_shutdown(git_mwindow_files_free); - - return git_strmap_alloc(&git__pack_cache); + git__pack_cache = NULL; + git_strmap_free(tmp); } -void git_mwindow_files_free(void) +int git_mwindow_global_init(void) { - git_strmap *tmp = git__pack_cache; + assert(!git__pack_cache); - git__pack_cache = NULL; - git_strmap_free(tmp); + git__on_shutdown(git_mwindow_files_free); + return git_strmap_alloc(&git__pack_cache); } int git_mwindow_get_pack(struct git_pack_file **out, const char *path) { int error; @@ -67,16 +62,10 @@ if (git_mutex_lock(&git__mwindow_mutex) < 0) { giterr_set(GITERR_OS, "failed to lock mwindow mutex"); return -1; } - if (git_mwindow_files_init() < 0) { - git_mutex_unlock(&git__mwindow_mutex); - git__free(packname); - return -1; - } - pos = git_strmap_lookup_index(git__pack_cache, packname); git__free(packname); if (git_strmap_valid_index(git__pack_cache, pos)) { pack = git_strmap_value_at(git__pack_cache, pos); @@ -294,11 +283,21 @@ * window to close and are above the limit, we still mmap the new * window. */ if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < 0) { - git__free(w); - return NULL; + /* + * The first error might be down to memory fragmentation even if + * we're below our soft limits, so free up what we can and try again. + */ + + while (git_mwindow_close_lru(mwf) == 0) + /* nop */; + + if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < 0) { + git__free(w); + return NULL; + } } ctl->mmap_calls++; ctl->open_windows++;