diff options
| author | Patrick Steinhardt <ps@pks.im> | 2024-09-30 11:13:45 +0200 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2024-09-30 11:23:05 -0700 |
| commit | a5aecb2cdc8c5f2c1501bdbe30c02959948d8442 (patch) | |
| tree | f4476a4632550a7b28d237b43f530f0cbe9d822f /line-log.c | |
| parent | fdf972a9df19915ef7bddf447bfecbcd0d8aea17 (diff) | |
| download | git-a5aecb2cdc8c5f2c1501bdbe30c02959948d8442.tar.xz | |
diff: improve lifecycle management of diff queues
The lifecycle management of diff queues is somewhat confusing:
- For most of the part this can be attributed to `DIFF_QUEUE_CLEAR()`,
which does not release any memory but rather initializes the queue,
only. This is in contrast to our common naming schema, where
"clearing" means that we release underlying memory and then
re-initialize the data structure such that it is ready to use.
- A second offender is `diff_free_queue()`, which does not free the
queue structure itself. It is rather a release-style function.
Refactor the code to make things less confusing. `DIFF_QUEUE_CLEAR()` is
replaced by `DIFF_QUEUE_INIT` and `diff_queue_init()`, while
`diff_free_queue()` is replaced by `diff_queue_release()`. While on it,
adapt callsites where we call `DIFF_QUEUE_CLEAR()` with the intent to
release underlying memory to instead call `diff_queue_clear()` to fix
memory leaks.
This memory leak is exposed by t4211, but plugging it alone does not
make the whole test suite pass.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'line-log.c')
| -rw-r--r-- | line-log.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/line-log.c b/line-log.c index 67c80b39a0..89e0ea4562 100644 --- a/line-log.c +++ b/line-log.c @@ -787,15 +787,14 @@ static void move_diff_queue(struct diff_queue_struct *dst, struct diff_queue_struct *src) { assert(src != dst); - memcpy(dst, src, sizeof(struct diff_queue_struct)); - DIFF_QUEUE_CLEAR(src); + memcpy(dst, src, sizeof(*dst)); + diff_queue_init(src); } static void filter_diffs_for_paths(struct line_log_data *range, int keep_deletions) { int i; - struct diff_queue_struct outq; - DIFF_QUEUE_CLEAR(&outq); + struct diff_queue_struct outq = DIFF_QUEUE_INIT; for (i = 0; i < diff_queued_diff.nr; i++) { struct diff_filepair *p = diff_queued_diff.queue[i]; @@ -850,12 +849,12 @@ static void queue_diffs(struct line_log_data *range, clear_pathspec(&opt->pathspec); parse_pathspec_from_ranges(&opt->pathspec, range); } - DIFF_QUEUE_CLEAR(&diff_queued_diff); + diff_queue_clear(&diff_queued_diff); diff_tree_oid(parent_tree_oid, tree_oid, "", opt); if (opt->detect_rename && diff_might_be_rename()) { /* must look at the full tree diff to detect renames */ clear_pathspec(&opt->pathspec); - DIFF_QUEUE_CLEAR(&diff_queued_diff); + diff_queue_clear(&diff_queued_diff); diff_tree_oid(parent_tree_oid, tree_oid, "", opt); @@ -1097,7 +1096,7 @@ static struct diff_filepair *diff_filepair_dup(struct diff_filepair *pair) static void free_diffqueues(int n, struct diff_queue_struct *dq) { for (int i = 0; i < n; i++) - diff_free_queue(&dq[i]); + diff_queue_clear(&dq[i]); free(dq); } @@ -1200,7 +1199,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c if (parent) add_line_range(rev, parent, parent_range); free_line_log_data(parent_range); - diff_free_queue(&queue); + diff_queue_clear(&queue); return changed; } |
