with me..
--HG--
branch : HEAD
)
AC_SUBST(ssldir)
+AC_ARG_WITH(gc,
+[ --with-gc Use Boehm garbage collector (currently broken)],
+ if test x$withval = xyes; then
+ want_gc=yes
+ else
+ if test "x$withval" = xno; then
+ want_gc=no
+ else
+ want_gc=yes
+ fi
+ fi,
+ want_gc=no)
+
AC_ARG_WITH(pop3d,
[ --with-pop3d Build POP3 server (default)],
if test x$withval = xno; then
AC_DEFINE(HAVE_SSL,, Build with SSL/TLS support)
fi
+dnl **
+dnl ** Garbage Collector
+dnl **
+
+if test "$want_gc" = "yes"; then
+ AC_CHECK_LIB(gc, GC_malloc, [
+ AC_CHECK_HEADERS(gc/gc.h gc.h)
+ AC_DEFINE(USE_GC,, Define if you want to use Boehm GC)
+ LIBS="$LIBS -lgc"
+ ], [
+ want_gc=no
+ ])
+fi
+
dnl **
dnl ** userdb and passdb checks
dnl **
#include <stdlib.h>
+#ifdef HAVE_GC_GC_H
+# include <gc/gc.h>
+#elif defined (HAVE_GC_H)
+# include <gc.h>
+#endif
+
/* Use malloc() and free() for all memory allocations. Useful for debugging
memory corruption. */
/* #define DISABLE_DATA_STACK */
# define INITIAL_STACK_SIZE (1024*32)
#endif
+#ifdef DEBUG
+# define CLEAR_CHR 0xde
+#elif defined(USE_GC)
+# define CLEAR_CHR 0
+#endif
+
struct stack_block {
struct stack_block *next;
frame_pos = 0;
if (unused_frame_blocks == NULL) {
/* allocate new block */
+#ifndef USE_GC
frame_block = calloc(sizeof(*frame_block), 1);
+#else
+ frame_block = GC_malloc(sizeof(*frame_block));
+ memset(frame_block, 0, sizeof(*frame_block));
+#endif
if (frame_block == NULL)
i_panic("t_push(): Out of memory");
} else {
return data_stack_frame++;
}
+#ifndef USE_GC
static void free_blocks(struct stack_block *block)
{
struct stack_block *next;
block = next;
}
}
+#endif
unsigned int t_pop(void)
{
/* update the current block */
current_block = current_frame_block->block[frame_pos];
current_block->left = current_frame_block->block_space_used[frame_pos];
-#ifdef DEBUG
+#ifdef CLEAR_CHR
memset(STACK_BLOCK_DATA(current_block) +
- (current_block->size - current_block->left), 0xde,
+ (current_block->size - current_block->left), CLEAR_CHR,
current_block->left);
#endif
if (current_block->next != NULL) {
/* free unused blocks */
+#ifndef USE_GC
free_blocks(current_block->next);
+#endif
current_block->next = NULL;
}
prev_size = current_block == NULL ? 0 : current_block->size;
alloc_size = nearest_power(prev_size + min_size);
+#ifndef USE_GC
block = malloc(SIZEOF_MEMBLOCK + alloc_size);
+#else
+ block = GC_malloc_atomic(SIZEOF_MEMBLOCK + alloc_size);
+#endif
if (block == NULL) {
i_panic("mem_block_alloc(): "
"Out of memory when allocating %"PRIuSIZE_T" bytes",
if (frame_pos != BLOCK_FRAME_COUNT-1)
i_panic("Missing t_pop() call");
+#ifndef USE_GC
while (unused_frame_blocks != NULL) {
struct stack_frame_block *frame_block = unused_frame_blocks;
unused_frame_blocks = unused_frame_blocks->prev;
- free(frame_block);
+ free(frame_block);
}
free(current_block);
free(unused_block);
+#endif
+ unused_frame_blocks = NULL;
+ current_block = NULL;
+ unused_block = NULL;
}
#else
+#ifdef USE_GC
+# error No GC with disabled data stack
+#endif
+
struct stack_frame {
struct stack_frame *next;
struct frame_alloc *allocs;
#include <stdlib.h>
+#ifdef HAVE_GC_GC_H
+# include <gc/gc.h>
+#elif defined (HAVE_GC_H)
+# include <gc.h>
+#endif
+
#define MAX_ALLOC_SIZE SSIZE_T_MAX
struct alloconly_pool {
pool_t pool_alloconly_create(const char *name, size_t size)
{
struct alloconly_pool *apool;
- int len;
+ size_t len;
- len = strlen(name);
+ len = strlen(name)+1;
- apool = calloc(SIZEOF_ALLOCONLYPOOL + len+1, 1);
+#ifndef USE_GC
+ apool = calloc(SIZEOF_ALLOCONLYPOOL + len, 1);
+#else
+ apool = GC_malloc(SIZEOF_ALLOCONLYPOOL + len);
+ memset(apool, 0, SIZEOF_ALLOCONLYPOOL + len);
+#endif
if (apool == NULL)
i_panic("pool_alloconly_create(): Out of memory");
apool->pool = static_alloconly_pool;
apool->refcount = 1;
- memcpy(apool->name, name, len+1);
+ memcpy(apool->name, name, len);
block_alloc(apool, size);
return (struct pool *) apool;
#ifdef DEBUG
memset(apool->block, 0xde, SIZEOF_POOLBLOCK + apool->block->size);
#endif
+
+#ifndef USE_GC
free(apool->block);
free(apool);
+#else
+ apool->block = NULL;
+ apool = NULL;
+#endif
}
static const char *pool_alloconly_get_name(pool_t pool)
}
#endif
+#ifndef USE_GC
block = calloc(size, 1);
+#else
+ block = GC_malloc(size);
+ memset(block, 0, size);
+#endif
if (block == NULL)
i_panic("block_alloc(): Out of memory");
block->prev = apool->block;
#ifdef DEBUG
memset(block, 0xde, SIZEOF_POOLBLOCK + block->size);
#endif
+#ifndef USE_GC
free(block);
+#endif
}
/* clear the block */
#include <stdlib.h>
+#ifdef HAVE_GC_GC_H
+# include <gc/gc.h>
+#elif defined (HAVE_GC_H)
+# include <gc.h>
+#endif
+
static const char *pool_system_get_name(pool_t pool);
static void pool_system_ref(pool_t pool);
static void pool_system_unref(pool_t pool);
if (size == 0 || size > SSIZE_T_MAX)
i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
+#ifndef USE_GC
mem = calloc(size, 1);
+#else
+ mem = GC_malloc(size);
+ memset(mem, 0, size);
+#endif
if (mem == NULL)
i_panic("pool_system_malloc(): Out of memory");
return mem;
}
-static void pool_system_free(pool_t pool __attr_unused__, void *mem)
+static void pool_system_free(pool_t pool __attr_unused__,
+ void *mem __attr_unused__)
{
+#ifndef USE_GC
if (mem != NULL)
free(mem);
+#endif
}
static void *pool_system_realloc(pool_t pool __attr_unused__, void *mem,
if (new_size == 0 || new_size > SSIZE_T_MAX)
i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
+#ifndef USE_GC
mem = realloc(mem, new_size);
+#else
+ mem = GC_realloc(mem, new_size);
+#endif
if (mem == NULL)
i_panic("pool_system_realloc(): Out of memory");