Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5356:48fe4fe9ef64 HEAD
Added system_clean_pool. default_pool is now set statically, so it can be
changed before calling lib_init(). Use malloc_usable_size() if it's
available for asserts and for implementing system_clean_pool.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 18 Mar 2007 03:57:11 +0200 |
parents | e83bf216cec2 |
children | ac0ef8053692 |
files | configure.in src/lib/Makefile.am src/lib/imem.c src/lib/imem.h src/lib/mempool-system-clean.c src/lib/mempool-system.c src/lib/mempool.h |
diffstat | 7 files changed, 186 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Sun Mar 18 03:53:19 2007 +0200 +++ b/configure.in Sun Mar 18 03:57:11 2007 +0200 @@ -15,7 +15,7 @@ AC_PROG_LIBTOOL AM_ICONV -AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h \ +AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h malloc.h \ sys/uio.h sys/sysmacros.h sys/resource.h sys/select.h libgen.h \ sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h \ mntent.h sys/mnttab.h sys/event.h sys/time.h sys/mkdev.h linux/dqblk_xfs.h \ @@ -436,7 +436,8 @@ strcasecmp stricmp vsnprintf vsyslog writev pread \ setrlimit setproctitle seteuid setreuid setegid setresgid \ strtoull strtouq setpriority quotactl getmntent kqueue kevent \ - getrusage backtrace_symbols walkcontext dirfd) + getrusage backtrace_symbols walkcontext dirfd \ + malloc_usable_size) dnl * I/O loop function have_ioloop=no @@ -1858,6 +1859,14 @@ AC_SUBST(sql_drivers) dnl ** +dnl ** Settings +dnl ** + +dnl get a list of setting .[ch] files, but list .h files first +SETTING_FILES=`find $srcdir/src -name '*settings.[[ch]]' ! -name all-settings.[[ch]] | sed -e s,$srcdir/src,./src,g -e 's,./src,$(top_srcdir)/src,g' -e 's/^\(.*\)\(.\)$/\2 \1\2/' | sort -r | sed s/^..//|tr '\n' ' '` +AC_SUBST(SETTING_FILES) + +dnl ** dnl ** Plugins dnl ** @@ -1889,6 +1898,7 @@ src/lib-imap/Makefile src/lib-index/Makefile src/lib-mail/Makefile +src/lib-master/Makefile src/lib-ntlm/Makefile src/lib-otp/Makefile src/lib-settings/Makefile @@ -1908,6 +1918,8 @@ src/master/Makefile src/pop3/Makefile src/pop3-login/Makefile +src/config/Makefile +src/log/Makefile src/util/Makefile src/plugins/Makefile src/plugins/acl/Makefile
--- a/src/lib/Makefile.am Sun Mar 18 03:53:19 2007 +0200 +++ b/src/lib/Makefile.am Sun Mar 18 03:57:11 2007 +0200 @@ -53,6 +53,7 @@ mempool-alloconly.c \ mempool-datastack.c \ mempool-system.c \ + mempool-system-clean.c \ mempool-unsafe-datastack.c \ mkdir-parents.c \ mmap-anon.c \
--- a/src/lib/imem.c Sun Mar 18 03:53:19 2007 +0200 +++ b/src/lib/imem.c Sun Mar 18 03:57:11 2007 +0200 @@ -2,7 +2,7 @@ #include "lib.h" -pool_t default_pool; +pool_t default_pool = &static_system_pool; void *i_malloc(size_t size) { @@ -73,8 +73,3 @@ va_end(args); return ret; } - -void imem_init(void) -{ - default_pool = system_pool; -}
--- a/src/lib/imem.h Sun Mar 18 03:53:19 2007 +0200 +++ b/src/lib/imem.h Sun Mar 18 03:57:11 2007 +0200 @@ -28,6 +28,4 @@ char *i_strconcat(const char *str1, ...) __attr_sentinel__ __attr_malloc__; -void imem_init(void); - #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/mempool-system-clean.c Sun Mar 18 03:57:11 2007 +0200 @@ -0,0 +1,158 @@ +/* Copyright (c) 2007 Timo Sirainen */ + +/* @UNSAFE: whole file */ + +#include "lib.h" +#include "safe-memset.h" +#include "mempool.h" + +#ifdef HAVE_MALLOC_H +# include <malloc.h> +#endif +#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_clean_get_name(pool_t pool); +static void pool_system_clean_ref(pool_t pool); +static void pool_system_clean_unref(pool_t *pool); +static void *pool_system_clean_malloc(pool_t pool, size_t size); +static void pool_system_clean_free(pool_t pool, void *mem); +static void *pool_system_clean_realloc(pool_t pool, void *mem, + size_t old_size, size_t new_size); +static void pool_system_clean_clear(pool_t pool); +static size_t pool_system_clean_get_max_easy_alloc_size(pool_t pool); + +static struct pool_vfuncs static_system_clean_pool_vfuncs = { + pool_system_clean_get_name, + + pool_system_clean_ref, + pool_system_clean_unref, + + pool_system_clean_malloc, + pool_system_clean_free, + + pool_system_clean_realloc, + + pool_system_clean_clear, + pool_system_clean_get_max_easy_alloc_size +}; + +static struct pool static_system_clean_pool = { + MEMBER(v) &static_system_clean_pool_vfuncs, + + MEMBER(alloconly_pool) FALSE, + MEMBER(datastack_pool) FALSE +}; + +pool_t system_clean_pool = &static_system_clean_pool; + +static const char *pool_system_clean_get_name(pool_t pool __attr_unused__) +{ + return "system clean"; +} + +static void pool_system_clean_ref(pool_t pool __attr_unused__) +{ +} + +static void pool_system_clean_unref(pool_t *pool __attr_unused__) +{ +} + +static size_t mem_get_size(void *mem) +{ +#ifdef USE_GC + return GC_size(mem); +#elif defined(HAVE_MALLOC_USABLE_SIZE) + return malloc_usable_size(mem); +#else + return ((size_t *)mem)[-1]; +#endif +} + +static void *pool_system_clean_malloc(pool_t pool __attr_unused__, size_t size) +{ + void *mem; + + if (size == 0 || size > SSIZE_T_MAX) + i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size); + +#ifdef USE_GC + mem = GC_malloc(size); +#else +#ifndef HAVE_MALLOC_USABLE_SIZE + size += sizeof(size_t); +#endif + mem = calloc(size, 1); +#endif + if (mem == NULL) { + i_fatal_status(FATAL_OUTOFMEM, + "pool_system_clean_malloc(): Out of memory"); + } +#if !defined(USE_GC) && !defined(HAVE_MALLOC_USABLE_SIZE) + { + size_t *saved_size = mem; + + *saved_size = size; + mem = saved_size + 1; + } +#endif + return mem; +} + +static void pool_system_clean_free(pool_t pool __attr_unused__, void *mem) +{ + if (mem != NULL) { + safe_memset(mem, 0, mem_get_size(mem)); +#ifndef USE_GC +#ifndef HAVE_MALLOC_USABLE_SIZE + mem = (size_t *)mem - 1; +#endif + free(mem); +#endif + } +} + +static void *pool_system_clean_realloc(pool_t pool __attr_unused__, void *mem, + size_t old_size, size_t new_size) +{ + void *new_mem; + + if (new_size == 0 || new_size > SSIZE_T_MAX) + i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size); + + new_mem = pool_system_clean_malloc(pool, new_size); + if (mem != NULL) { +#if !defined(USE_GC) && defined(HAVE_MALLOC_USABLE_SIZE) + i_assert(old_size == (size_t)-1 || + old_size <= malloc_usable_size(mem)); +#endif + memcpy(new_mem, mem, mem_get_size(mem)); + pool_system_clean_free(pool, mem); + + if (old_size < new_size) { + /* clear new data */ + memset((char *)new_mem + old_size, 0, + new_size - old_size); + } + } + + return new_mem; +} + +static void __attr_noreturn__ +pool_system_clean_clear(pool_t pool __attr_unused__) +{ + i_panic("pool_system_clean_clear() must not be called"); +} + +static size_t +pool_system_clean_get_max_easy_alloc_size(pool_t pool __attr_unused__) +{ + return 0; +}
--- a/src/lib/mempool-system.c Sun Mar 18 03:53:19 2007 +0200 +++ b/src/lib/mempool-system.c Sun Mar 18 03:57:11 2007 +0200 @@ -6,6 +6,9 @@ #include "mempool.h" #include <stdlib.h> +#ifdef HAVE_MALLOC_H +# include <malloc.h> +#endif #ifdef HAVE_GC_GC_H # include <gc/gc.h> @@ -38,14 +41,13 @@ pool_system_get_max_easy_alloc_size }; -static struct pool static_system_pool = { +struct pool static_system_pool = { MEMBER(v) &static_system_pool_vfuncs, MEMBER(alloconly_pool) FALSE, MEMBER(datastack_pool) FALSE }; - pool_t system_pool = &static_system_pool; static const char *pool_system_get_name(pool_t pool __attr_unused__) @@ -105,6 +107,10 @@ "pool_system_realloc(): Out of memory"); } +#if !defined(USE_GC) && defined(HAVE_MALLOC_USABLE_SIZE) + i_assert(old_size == (size_t)-1 || mem == NULL || + old_size <= malloc_usable_size(mem)); +#endif if (old_size < new_size) { /* clear new data */ memset((char *) mem + old_size, 0, new_size - old_size);
--- a/src/lib/mempool.h Sun Mar 18 03:53:19 2007 +0200 +++ b/src/lib/mempool.h Sun Mar 18 03:57:11 2007 +0200 @@ -48,6 +48,10 @@ /* system_pool uses calloc() + realloc() + free() */ extern pool_t system_pool; +extern struct pool static_system_pool; +/* Similar to pool_alloconly_create_clean(), but uses system_pool to + allocate the memory. */ +extern pool_t system_clean_pool; /* memory allocated from data_stack is valid only until next t_pop() call. No checks are performed. */