summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <carlos@cmartin.tk>2011-10-15 23:09:05 +0200
committerCarlos Martín Nieto <carlos@cmartin.tk>2011-10-15 23:25:48 +0200
commit5fa1bed0f7da8959f561c49fba6975812f80546a (patch)
tree41d27ba01eff50ee5823db298cbb8d5af7b3bd8f
parenta014a083d9010e7f1ad0a00e6b48b75d6616edde (diff)
downloadlibgit2-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.c17
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;