diff options
author | Carlos Martín Nieto <carlos@cmartin.tk> | 2011-10-15 23:09:05 +0200 |
---|---|---|
committer | Carlos Martín Nieto <carlos@cmartin.tk> | 2011-10-15 23:25:48 +0200 |
commit | 5fa1bed0f7da8959f561c49fba6975812f80546a (patch) | |
tree | 41d27ba01eff50ee5823db298cbb8d5af7b3bd8f | |
parent | a014a083d9010e7f1ad0a00e6b48b75d6616edde (diff) | |
download | libgit2-5fa1bed0f7da8959f561c49fba6975812f80546a.tar.gz |
mwindow: close LRU window properly
Remove a wrong call to git_mwindow_close which caused a segfault if it
ever did run. In that same piece of code, if the LRU was from the
first wiindow in the list in a different file, we didn't update that
list, so the first element had been freed.
Fix these two issues.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
-rw-r--r-- | src/mwindow.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/mwindow.c b/src/mwindow.c index c126fa2bd..e53477e98 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -116,25 +116,28 @@ void git_mwindow_scan_lru( static int git_mwindow_close_lru(git_mwindow_file *mwf) { unsigned int i; - git_mwindow *lru_w = NULL, *lru_l = NULL; + git_mwindow *lru_w = NULL, *lru_l = NULL, **list = &mwf->windows; /* FIMXE: Does this give us any advantage? */ if(mwf->windows) git_mwindow_scan_lru(mwf, &lru_w, &lru_l); for (i = 0; i < ctl.windowfiles.length; ++i) { - git_mwindow_scan_lru(git_vector_get(&ctl.windowfiles, i), &lru_w, &lru_l); + git_mwindow *last = lru_w; + git_mwindow_file *cur = git_vector_get(&ctl.windowfiles, i); + git_mwindow_scan_lru(cur, &lru_w, &lru_l); + if (lru_w != last) + list = &cur->windows; } if (lru_w) { - git_mwindow_close(&lru_w); ctl.mapped -= lru_w->window_map.len; git_futils_mmap_free(&lru_w->window_map); if (lru_l) lru_l->next = lru_w->next; else - mwf->windows = lru_w->next; + *list = lru_w->next; free(lru_w); ctl.open_windows--; @@ -167,7 +170,11 @@ static git_mwindow *new_window(git_mwindow_file *mwf, git_file fd, git_off_t siz while(ctl.mapped_limit < ctl.mapped && git_mwindow_close_lru(mwf) == GIT_SUCCESS) {} - /* FIXME: Shouldn't we error out if there's an error in closing lru? */ + /* + * We treat ctl.mapped_limit as a soft limit. If we can't find a + * 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) < GIT_SUCCESS) goto cleanup; |