From: Timo Sirainen Date: Fri, 5 May 2023 14:10:55 +0000 (+0300) Subject: lib: Add pool_add_external_ref() to allow pools to reference other pools X-Git-Tag: 2.4.0~2086 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5610cfde1fbc8d2046598e9e8a3042abddde1e06;p=thirdparty%2Fdovecot%2Fcore.git lib: Add pool_add_external_ref() to allow pools to reference other pools When the pool is destroyed, all its external references are unreferenced. --- diff --git a/src/lib/lib.h b/src/lib/lib.h index 7d945780c7..474fbf190b 100644 --- a/src/lib/lib.h +++ b/src/lib/lib.h @@ -37,6 +37,10 @@ #include "macros.h" #include "failures.h" +typedef struct buffer buffer_t; +typedef struct buffer string_t; + +#include "array-decl.h" /* ARRAY*()s may exist in any header */ #include "malloc-overflow.h" #include "data-stack.h" #include "mempool.h" @@ -57,7 +61,6 @@ struct ostream; typedef void lib_atexit_callback_t(void); -#include "array-decl.h" /* ARRAY*()s may exist in any header */ #include "bits.h" #include "hash-decl.h" /* HASH_TABLE*()s may exist in any header */ #include "strfuncs.h" diff --git a/src/lib/mempool-alloconly.c b/src/lib/mempool-alloconly.c index a9e8cd701a..798ea84f90 100644 --- a/src/lib/mempool-alloconly.c +++ b/src/lib/mempool-alloconly.c @@ -348,6 +348,7 @@ static void pool_alloconly_unref(pool_t *pool) if (--apool->refcount > 0) return; + pool_external_refs_unref(&apool->pool); pool_alloconly_destroy(apool); } diff --git a/src/lib/mempool.c b/src/lib/mempool.c index a657481f93..68ec8f6684 100644 --- a/src/lib/mempool.c +++ b/src/lib/mempool.c @@ -1,6 +1,7 @@ /* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" /* The various implementations of pools API assume that they'll never be asked for more than SSIZE_T_MAX bytes. This is a sanity check to make @@ -23,3 +24,21 @@ size_t pool_get_exp_grown_size(pool_t pool, size_t old_size, size_t min_size) i_assert(exp_size >= min_size); return exp_size; } + +void pool_add_external_ref(pool_t pool, pool_t ref_pool) +{ + if (!array_is_created(&pool->external_refs)) + i_array_init(&pool->external_refs, 1); + array_push_back(&pool->external_refs, &ref_pool); + pool_ref(ref_pool); +} + +void pool_external_refs_unref(pool_t pool) +{ + if (array_is_created(&pool->external_refs)) { + pool_t external_pool; + array_foreach_elem(&pool->external_refs, external_pool) + pool_unref(&external_pool); + array_free(&pool->external_refs); + } +} diff --git a/src/lib/mempool.h b/src/lib/mempool.h index 9c7aca0581..918a6d4e6e 100644 --- a/src/lib/mempool.h +++ b/src/lib/mempool.h @@ -46,6 +46,7 @@ struct pool_vfuncs { struct pool { const struct pool_vfuncs *v; + ARRAY(pool_t) external_refs; bool alloconly_pool:1; bool datastack_pool:1; @@ -86,6 +87,10 @@ pool_t pool_allocfree_create_clean(const char *name); old_size + 1. */ size_t pool_get_exp_grown_size(pool_t pool, size_t old_size, size_t min_size); +/* Reference another memory pool in the given pool. When the pool is freed, + the referenced memory pools are also unreferenced. */ +void pool_add_external_ref(pool_t pool, pool_t ref_pool); + /* We require sizeof(type) to be <= UINT_MAX. This allows compiler to optimize away the entire MALLOC_MULTIPLY() call on 64bit systems. */ #define p_new(pool, type, count) \ @@ -175,5 +180,6 @@ size_t pool_allocfree_get_total_alloc_size(pool_t pool); /* private: */ void pool_system_free(pool_t pool, void *mem); +void pool_external_refs_unref(pool_t pool); #endif