[PATCH 24/24] revisions API: have release_revisions() release "topo_walk_info"
From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2022-03-09 13:18:55
Subsystem:
the rest · Maintainer:
Linus Torvalds
Refactor the existing reset_topo_walk() into a thin wrapper for a
release_revisions_topo_walk_info() + resetting the member to "NULL",
and call release_revisions_topo_walk_info() from release_revisions().
This fixes memory leaks that have been with us ever since
"topo_walk_info" was added to revision.[ch] in
f0d9cc4196a (revision.c: begin refactoring --topo-order logic,
2018-11-01).
Due to various other leaks this makes no tests pass in their entirety,
but e.g. before this running this on git.git:
./git -P log --pretty=tformat:"%P %H | %s" --parents --full-history --topo-order -3 -- README.md
Would report under SANITIZE=leak:
SUMMARY: LeakSanitizer: 531064 byte(s) leaked in 6 allocation(s).
Now we'll free all of that memory.
Signed-off-by: Ævar Arnfjörð Bjarmason <redacted>
---
revision.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/revision.c b/revision.c
index 9d03e7805ff..5a9400667df 100644
--- a/revision.c
+++ b/revision.c@@ -2945,6 +2945,8 @@ static void release_revisions_mailmap(struct string_list *mailmap) free(mailmap); } +static void release_revisions_topo_walk_info(struct topo_walk_info *info); + void release_revisions(struct rev_info *revs) { if (!revs)
@@ -2960,6 +2962,7 @@ void release_revisions(struct rev_info *revs) /* TODO (need to handle "no_free"): diff_free(&revs->diffopt) */ diff_free(&revs->pruning); reflog_walk_info_release(revs->reflog_info); + release_revisions_topo_walk_info(revs->topo_walk_info); } static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child)
@@ -3472,17 +3475,24 @@ static void compute_indegrees_to_depth(struct rev_info *revs, indegree_walk_step(revs); } -static void reset_topo_walk(struct rev_info *revs) +static void release_revisions_topo_walk_info(struct topo_walk_info *info) { - struct topo_walk_info *info = revs->topo_walk_info; - + if (!info) + return; clear_prio_queue(&info->explore_queue); clear_prio_queue(&info->indegree_queue); clear_prio_queue(&info->topo_queue); clear_indegree_slab(&info->indegree); clear_author_date_slab(&info->author_date); + free(info); +} + +static void reset_topo_walk(struct rev_info *revs) +{ + struct topo_walk_info *info = revs->topo_walk_info; - FREE_AND_NULL(revs->topo_walk_info); + release_revisions_topo_walk_info(info); + revs->topo_walk_info = NULL; } static void init_topo_walk(struct rev_info *revs)
--
2.35.1.1295.g6b025d3e231