aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcebka@mailsupport.rambler.ru <cebka@mailsupport.rambler.ru>2008-10-14 05:24:07 +0400
committercebka@mailsupport.rambler.ru <cebka@mailsupport.rambler.ru>2008-10-14 05:24:07 +0400
commit3f8572f20960a02b334d09c809513d5ab25012a5 (patch)
treedd0fa627691c82abdb8e6b5ca55572525b5b0259
parentfd84d363d87414274dc24e77f301ab5c966ede0b (diff)
downloadrspamd-3f8572f20960a02b334d09c809513d5ab25012a5.tar.gz
rspamd-3f8572f20960a02b334d09c809513d5ab25012a5.zip
* Implement destructors stack in memory pool, so there is now
convinient way to free objects in pool that was allocated by other memory allocation mechanics (e.g. GObject). Destructors must be added in pool manually by calling memory_pool_add_destructor function.
-rw-r--r--cfg_utils.c1
-rw-r--r--mem_pool.c23
-rw-r--r--mem_pool.h18
3 files changed, 38 insertions, 4 deletions
diff --git a/cfg_utils.c b/cfg_utils.c
index 3f46b0dd8..7f64e4552 100644
--- a/cfg_utils.c
+++ b/cfg_utils.c
@@ -494,6 +494,7 @@ parse_regexp (memory_pool_t *pool, char *line)
*end = '\0';
result->regexp = g_regex_new (begin, regexp_flags, 0, &err);
result->regexp_text = memory_pool_strdup (pool, begin);
+ memory_pool_add_destructor (pool, (pool_destruct_func)g_regex_unref, (void *)result->regexp);
*end = '/';
return result;
diff --git a/mem_pool.c b/mem_pool.c
index fc14af790..56fc0ef78 100644
--- a/mem_pool.c
+++ b/mem_pool.c
@@ -42,6 +42,7 @@ memory_pool_new (size_t size)
new = g_malloc (sizeof (memory_pool_t));
new->cur_pool = pool_chain_new (size);
new->first_pool = new->cur_pool;
+ new->destructors = NULL;
return new;
}
@@ -112,9 +113,31 @@ memory_pool_strdup (memory_pool_t *pool, const char *src)
}
void
+memory_pool_add_destructor (memory_pool_t *pool, pool_destruct_func func, void *data)
+{
+ struct _pool_destructors *cur;
+
+ cur = memory_pool_alloc (pool, sizeof (struct _pool_destructors));
+ if (cur) {
+ cur->func = func;
+ cur->data = data;
+ cur->prev = pool->destructors;
+ pool->destructors = cur;
+ }
+}
+
+void
memory_pool_delete (memory_pool_t *pool)
{
struct _pool_chain *cur = pool->first_pool, *tmp;
+ struct _pool_destructors *destructor = pool->destructors;
+
+ /* Call all pool destructors */
+ while (destructor) {
+ destructor->func (destructor->data);
+ destructor = destructor->prev;
+ }
+
while (cur) {
tmp = cur;
cur = cur->next;
diff --git a/mem_pool.h b/mem_pool.h
index f5d3e4238..d20a5edcd 100644
--- a/mem_pool.h
+++ b/mem_pool.h
@@ -3,15 +3,24 @@
#include <sys/types.h>
#include <glib.h>
+
+typedef void (*pool_destruct_func)(void *ptr);
+
struct _pool_chain {
- u_char *begin;
- u_char *pos;
- size_t len;
- struct _pool_chain *next;
+ u_char *begin;
+ u_char *pos;
+ size_t len;
+ struct _pool_chain *next;
+};
+struct _pool_destructors {
+ pool_destruct_func func;
+ void *data;
+ struct _pool_destructors *prev;
};
typedef struct memory_pool_s {
struct _pool_chain *cur_pool;
struct _pool_chain *first_pool;
+ struct _pool_destructors *destructors;
} memory_pool_t;
typedef struct memory_pool_stat_s {
@@ -24,6 +33,7 @@ memory_pool_t* memory_pool_new (size_t size);
void* memory_pool_alloc (memory_pool_t* pool, size_t size);
void* memory_pool_alloc0 (memory_pool_t* pool, size_t size);
char* memory_pool_strdup (memory_pool_t* pool, const char *src);
+void memory_pool_add_destructor (memory_pool_t *pool, pool_destruct_func func, void *data);
void memory_pool_delete (memory_pool_t* pool);
void memory_pool_stat (memory_pool_stat_t *st);