reftable/writer: unify releasing memory

There are two code paths which release memory of the reftable writer: - `reftable_writer_close()` releases internal state after it has written data. - `reftable_writer_free()` releases the block that was written to and the writer itself. Both code paths free different parts of the writer, and consequently the caller must make sure to call both. And while callers mostly do this already, this falls apart when a write failure causes the caller to skip calling `reftable_write_close()`. Introduce a new function `reftable_writer_release()` that releases all internal state and call it from both paths. Like this it is fine for the caller to not call `reftable_writer_close()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 8, 2024 at 14:24 UTC 60dd319519b41cc5cc79bdef5ee8556297db6984
1 file changed +15 -8
reftable/writer.c
+15 -8
@@ -149,11 +149,21 @@ void reftable_writer_set_limits(struct reftable_writer *w, uint64_t min,
149 w->max_update_index = max;
150 }
151
152 +static void writer_release(struct reftable_writer *w)
153 +{
154 + if (w) {
155 + reftable_free(w->block);
156 + w->block = NULL;
157 + block_writer_release(&w->block_writer_data);
158 + w->block_writer = NULL;
159 + writer_clear_index(w);
160 + strbuf_release(&w->last_key);
161 + }
162 +}
163 +
164 void reftable_writer_free(struct reftable_writer *w)
165 {
154 - if (!w)
155 - return;
156 - reftable_free(w->block);
166 + writer_release(w);
167 reftable_free(w);
168 }
169
@@ -643,16 +653,13 @@ int reftable_writer_close(struct reftable_writer *w)
653 }
654
655 done:
646 - /* free up memory. */
647 - block_writer_release(&w->block_writer_data);
648 - writer_clear_index(w);
649 - strbuf_release(&w->last_key);
656 + writer_release(w);
657 return err;
658 }
659
660 static void writer_clear_index(struct reftable_writer *w)
661 {
655 - for (size_t i = 0; i < w->index_len; i++)
662 + for (size_t i = 0; w->index && i < w->index_len; i++)
663 strbuf_release(&w->index[i].last_key);
664 FREE_AND_NULL(w->index);
665 w->index_len = 0;