- memory pools would be used in modules for allocating task specific data without freeing it separately
- memory pools growth is implemented as multiplying by 2 its length (for avoiding multiply reallocs)
- when memory pool is freed all data that was allocated from this pool is freed too
LEX_OUTPUT="cfg_lex.c"
CONFIG="config.h"
-SOURCES="upstream.c cfg_utils.c memcached.c main.c util.c worker.c fstring.c url.c perl.c plugins/surbl.c ${LEX_OUTPUT} ${YACC_OUTPUT}"
+SOURCES="upstream.c cfg_utils.c memcached.c main.c util.c worker.c fstring.c url.c perl.c mem_pool.c plugins/surbl.c ${LEX_OUTPUT} ${YACC_OUTPUT}"
MODULES="surbl"
CFLAGS="$CFLAGS -W -Wpointer-arith -Wno-unused-parameter"
CFLAGS="$CFLAGS "
LDFLAGS="$LDFLAGS -L/usr/lib -L${LOCALBASE}/lib"
OPT_FLAGS="-O -pipe -fno-omit-frame-pointer"
-DEPS="config.h cfg_file.h memcached.h util.h main.h upstream.h fstring.h url.h perl.h ${LEX_OUTPUT} ${YACC_OUTPUT}"
+DEPS="config.h cfg_file.h memcached.h util.h main.h upstream.h fstring.h url.h perl.h mem_pool.h ${LEX_OUTPUT} ${YACC_OUTPUT}"
EXEC=rspamd
USER=postfix
GROUP=postfix
#include <event.h>
#include "fstring.h"
+#include "mem_pool.h"
#include "url.h"
#include "memcached.h"
TAILQ_HEAD (chainsq, chain_result) chain_results;
struct config_file *cfg;
struct save_point save;
+ /* Memory pool that is associated with this task */
+ memory_pool_t *task_pool;
};
struct module_ctx {
--- /dev/null
+#include <sys/types.h>
+#include <glib.h>
+#include "mem_pool.h"
+
+memory_pool_t*
+memory_pool_new (size_t size)
+{
+ memory_pool_t *new;
+
+ new = g_malloc (sizeof (memory_pool_t));
+ new->begin = g_malloc (size);
+ new->len = size;
+ new->pos = new->begin;
+
+ return new;
+}
+
+void *
+memory_pool_alloc (memory_pool_t *pool, size_t size)
+{
+ u_char *tmp;
+ if (pool) {
+ if (pool->len < (pool->pos - pool->begin) + size) {
+ /* Grow pool */
+ if (pool->len > size) {
+ pool->len *= 2;
+ }
+ else {
+ pool->len += size + pool->len;
+ }
+ pool->begin = g_realloc (pool->begin, pool->len);
+ return memory_pool_alloc (pool, size);
+ }
+ tmp = pool->pos;
+ pool->pos += size;
+ return tmp;
+ }
+ return NULL;
+}
+
+void memory_pool_free (memory_pool_t *pool)
+{
+ if (pool) {
+ g_free (pool->begin);
+ g_free (pool);
+ }
+}
+
+/*
+ * vi:ts=4
+ */
--- /dev/null
+#ifndef RSPAMD_MEM_POOL_H
+#define RSPAMD_MEM_POOL_H
+
+#include <sys/types.h>
+#include <glib.h>
+
+typedef struct memory_pool_s {
+ u_char *begin;
+ u_char *pos;
+ size_t len;
+ size_t used;
+} memory_pool_t;
+
+memory_pool_t* memory_pool_new (size_t size);
+void* memory_pool_alloc (memory_pool_t* pool, size_t size);
+void memory_pool_free (memory_pool_t* pool);
+
+#endif
memc_close_ctx (task->memc_ctx);
free (task->memc_ctx);
}
+ if (task->task_pool) {
+ memory_pool_free (task->task_pool);
+ }
while (!TAILQ_EMPTY (&task->urls)) {
cur = TAILQ_FIRST (&task->urls);
TAILQ_REMOVE (&task->urls, cur, next);
TAILQ_INIT (&new_task->results);
TAILQ_INIT (&new_task->parts);
new_task->memc_ctx = malloc (sizeof (memcached_ctx_t));
+ new_task->task_pool = memory_pool_new (1024);
if (new_task->memc_ctx == NULL) {
msg_err ("accept_socket: cannot allocate memory for memcached ctx, %m");
}