From 243e68b552b1d27dd8f86c35394551c124652ed2 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 27 Apr 2022 11:33:13 +0200 Subject: [PATCH] BUG/MINOR: pools: make sure to also destroy shared pools in pool_destroy_all() In issue #1677, Tim reported that we don't correctly free some shared pools on exit. What happens in fact is that pool_destroy() is meant to be called once per pool *pointer*, as it decrements the use count for each pass and only releases the pool when it reaches zero. But since pool_destroy_all() iterates over the pools list, it visits each pool only once and will not eliminate some of them, which thus remain in the list. In an ideal case, the function should loop over all pools for as long as the list is not empty, but that's pointless as we know we're exiting, so let's just set the users count to 1 before the call so that pool_destroy() knows it can delete and release the entry. This could be backported to all versions (memory.c in 2.0 and older) but it's not a real problem in practice. --- src/pool.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pool.c b/src/pool.c index 4c39978cf..83525311f 100644 --- a/src/pool.c +++ b/src/pool.c @@ -837,8 +837,14 @@ void pool_destroy_all() { struct pool_head *entry, *back; - list_for_each_entry_safe(entry, back, &pools, list) + list_for_each_entry_safe(entry, back, &pools, list) { + /* there's only one occurrence of each pool in the list, + * and we're existing instead of looping on the whole + * list just to decrement users, force it to 1 here. + */ + entry->users = 1; pool_destroy(entry); + } } /* This function dumps memory usage information into the trash buffer. */