[dovecot-cvs] dovecot/src/lib mempool-unsafe-datastack.c,NONE,1.1 Makefile.am,1.33,1.34 mempool-alloconly.c,1.24,1.25 mempool-datastack.c,1.9,1.10 mempool-system.c,1.13,1.14 mempool.h,1.11,1.12 str.c,1.11,1.12 strfuncs.c,1.32,1.33

cras at procontrol.fi cras at procontrol.fi
Sun Sep 21 20:21:39 EEST 2003


Update of /home/cvs/dovecot/src/lib
In directory danu:/tmp/cvs-serv17131/lib

Modified Files:
	Makefile.am mempool-alloconly.c mempool-datastack.c 
	mempool-system.c mempool.h str.c strfuncs.c 
Added Files:
	mempool-unsafe-datastack.c 
Log Message:
data_stack_pool split into two: unsafe_data_stack_pool which works like
before, and a new one which verifies that stack frame stays the same
whenever the pool is accessed.



--- NEW FILE: mempool-unsafe-datastack.c ---
/* Copyright (c) 2002-2003 Timo Sirainen */

#include "lib.h"
#include "mempool.h"

#include <stdlib.h>

static const char *pool_unsafe_data_stack_get_name(pool_t pool);
static void pool_unsafe_data_stack_ref(pool_t pool);
static void pool_unsafe_data_stack_unref(pool_t pool);
static void *pool_unsafe_data_stack_malloc(pool_t pool, size_t size);
static void pool_unsafe_data_stack_free(pool_t pool, void *mem);
static void *pool_unsafe_data_stack_realloc(pool_t pool, void *mem,
					    size_t old_size, size_t new_size);
static void pool_unsafe_data_stack_clear(pool_t pool);

static struct pool static_unsafe_data_stack_pool = {
	pool_unsafe_data_stack_get_name,

	pool_unsafe_data_stack_ref,
	pool_unsafe_data_stack_unref,

	pool_unsafe_data_stack_malloc,
	pool_unsafe_data_stack_free,

	pool_unsafe_data_stack_realloc,

	pool_unsafe_data_stack_clear,

	TRUE,
	TRUE
};

pool_t unsafe_data_stack_pool = &static_unsafe_data_stack_pool;

static const char *pool_unsafe_data_stack_get_name(pool_t pool __attr_unused__)
{
	return "unsafe data stack";
}

static void pool_unsafe_data_stack_ref(pool_t pool __attr_unused__)
{
}

static void pool_unsafe_data_stack_unref(pool_t pool __attr_unused__)
{
}

static void *pool_unsafe_data_stack_malloc(pool_t pool __attr_unused__,
					   size_t size)
{
	if (size == 0 || size > SSIZE_T_MAX)
		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);

	return t_malloc0(size);
}

static void pool_unsafe_data_stack_free(pool_t pool __attr_unused__,
					void *mem __attr_unused__)
{
}

static void *pool_unsafe_data_stack_realloc(pool_t pool __attr_unused__,
					    void *mem,
					    size_t old_size, size_t new_size)
{
	void *new_mem;

	/* @UNSAFE */
	if (new_size == 0 || new_size > SSIZE_T_MAX)
		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);

	if (mem == NULL)
		return pool_unsafe_data_stack_malloc(pool, new_size);

	if (old_size >= new_size)
		return mem;

	if (!t_try_realloc(mem, new_size)) {
		new_mem = t_malloc(new_size);
		memcpy(new_mem, mem, old_size);
		mem = new_mem;
	}

	memset((char *) mem + old_size, 0, new_size - old_size);
	return mem;
}

static void pool_unsafe_data_stack_clear(pool_t pool __attr_unused__)
{
}

Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/lib/Makefile.am,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- Makefile.am	24 Aug 2003 12:43:53 -0000	1.33
+++ Makefile.am	21 Sep 2003 16:21:37 -0000	1.34
@@ -35,6 +35,7 @@
 	mempool-alloconly.c \
 	mempool-datastack.c \
 	mempool-system.c \
+	mempool-unsafe-datastack.c \
 	mkdir-parents.c \
 	mmap-anon.c \
 	mmap-util.c \

Index: mempool-alloconly.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/mempool-alloconly.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- mempool-alloconly.c	26 Aug 2003 21:18:16 -0000	1.24
+++ mempool-alloconly.c	21 Sep 2003 16:21:37 -0000	1.25
@@ -57,7 +57,8 @@
 
 	pool_alloconly_clear,
 
-	TRUE
+	TRUE,
+	FALSE
 };
 
 pool_t pool_alloconly_create(const char *name, size_t size)

Index: mempool-datastack.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/mempool-datastack.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- mempool-datastack.c	26 Aug 2003 21:18:16 -0000	1.9
+++ mempool-datastack.c	21 Sep 2003 16:21:37 -0000	1.10
@@ -27,45 +27,87 @@
 
 	pool_data_stack_clear,
 
+	TRUE,
 	TRUE
 };
 
-pool_t data_stack_pool = &static_data_stack_pool;
+struct datastack_pool {
+	struct pool pool;
+	int refcount;
+
+	unsigned int data_stack_frame;
+};
+
+pool_t pool_datastack_create(void)
+{
+	struct datastack_pool *dpool;
+
+	dpool = t_new(struct datastack_pool, 1);
+	dpool->pool = static_data_stack_pool;
+	dpool->refcount = 1;
+	dpool->data_stack_frame = data_stack_frame;
+	return &dpool->pool;
+}
 
 static const char *pool_data_stack_get_name(pool_t pool __attr_unused__)
 {
 	return "data stack";
 }
 
-static void pool_data_stack_ref(pool_t pool __attr_unused__)
+static void pool_data_stack_ref(pool_t pool)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
+
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_ref(): stack frame changed");
+
+	dpool->refcount++;
 }
 
-static void pool_data_stack_unref(pool_t pool __attr_unused__)
+static void pool_data_stack_unref(pool_t pool)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
+
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_unref(): stack frame changed");
+
+	dpool->refcount--;
+	i_assert(dpool->refcount >= 0);
 }
 
 static void *pool_data_stack_malloc(pool_t pool __attr_unused__, size_t size)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
+
 	if (size == 0 || size > SSIZE_T_MAX)
 		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
 
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_malloc(): stack frame changed");
+
 	return t_malloc0(size);
 }
 
-static void pool_data_stack_free(pool_t pool __attr_unused__,
-				 void *mem __attr_unused__)
+static void pool_data_stack_free(pool_t pool, void *mem __attr_unused__)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
+
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_free(): stack frame changed");
 }
 
-static void *pool_data_stack_realloc(pool_t pool __attr_unused__, void *mem,
+static void *pool_data_stack_realloc(pool_t pool, void *mem,
 				     size_t old_size, size_t new_size)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
 	void *new_mem;
 
 	/* @UNSAFE */
 	if (new_size == 0 || new_size > SSIZE_T_MAX)
 		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
+
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_realloc(): stack frame changed");
 
 	if (mem == NULL)
 		return pool_data_stack_malloc(pool, new_size);

Index: mempool-system.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/mempool-system.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mempool-system.c	26 Aug 2003 21:18:16 -0000	1.13
+++ mempool-system.c	21 Sep 2003 16:21:37 -0000	1.14
@@ -29,7 +29,8 @@
 
 	pool_system_clear,
 
-        FALSE
+	FALSE,
+	FALSE
 };
 
 pool_t system_pool = &static_system_pool;

Index: mempool.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib/mempool.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- mempool.h	19 May 2003 09:50:24 -0000	1.11
+++ mempool.h	21 Sep 2003 16:21:37 -0000	1.12
@@ -29,17 +29,24 @@
 	void (*clear)(pool_t pool);
 
 	unsigned int alloconly_pool:1;
+	unsigned int datastack_pool:1;
 };
 
 /* system_pool uses calloc() + realloc() + free() */
 extern pool_t system_pool;
 
-/* memory allocated from data_stack is valid only until next t_pop() call. */
-extern pool_t data_stack_pool;
+/* memory allocated from data_stack is valid only until next t_pop() call.
+   No checks are performed. */
+extern pool_t unsafe_data_stack_pool;
 
 /* Create a new alloc-only pool. Note that `size' specifies the initial
    malloc()ed block size, part of it is used internally. */
 pool_t pool_alloconly_create(const char *name, size_t size);
+
+/* When allocating memory from returned pool, the data stack frame must be
+   the same as it was when calling this function. pool_unref() also checks
+   that the stack frame is the same. This should make it quite safe to use. */
+pool_t pool_datastack_create(void);
 
 /* Pools should be used through these macros: */
 #define pool_get_name(pool) (pool)->get_name(pool)

Index: str.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/str.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- str.c	8 Sep 2003 01:29:07 -0000	1.11
+++ str.c	21 Sep 2003 16:21:37 -0000	1.12
@@ -14,7 +14,7 @@
 
 string_t *t_str_new(size_t initial_size)
 {
-	return str_new(data_stack_pool, initial_size);
+	return str_new(pool_datastack_create(), initial_size);
 }
 
 void str_free(string_t *str)

Index: strfuncs.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/strfuncs.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- strfuncs.c	8 Sep 2003 01:29:07 -0000	1.32
+++ strfuncs.c	21 Sep 2003 16:21:37 -0000	1.33
@@ -197,7 +197,7 @@
 
 	i_assert(format != NULL);
 
-	if (pool != data_stack_pool)
+	if (!pool->datastack_pool)
 		t_push();
 
 	VA_COPY(args2, args);
@@ -210,7 +210,7 @@
 #else
 	vsprintf(ret, format, args2);
 #endif
-	if (pool != data_stack_pool)
+	if (!pool->datastack_pool)
 		t_pop();
 	return ret;
 }
@@ -277,27 +277,27 @@
 
 const char *t_strdup(const char *str)
 {
-	return p_strdup(data_stack_pool, str);
+	return p_strdup(unsafe_data_stack_pool, str);
 }
 
 char *t_strdup_noconst(const char *str)
 {
-	return p_strdup(data_stack_pool, str);
+	return p_strdup(unsafe_data_stack_pool, str);
 }
 
 const char *t_strdup_empty(const char *str)
 {
-	return p_strdup_empty(data_stack_pool, str);
+	return p_strdup_empty(unsafe_data_stack_pool, str);
 }
 
 const char *t_strdup_until(const void *start, const void *end)
 {
-	return p_strdup_until(data_stack_pool, start, end);
+	return p_strdup_until(unsafe_data_stack_pool, start, end);
 }
 
 const char *t_strndup(const void *str, size_t max_chars)
 {
-	return p_strndup(data_stack_pool, str, max_chars);
+	return p_strndup(unsafe_data_stack_pool, str, max_chars);
 }
 
 const char *t_strdup_printf(const char *format, ...)
@@ -306,7 +306,7 @@
 	const char *ret;
 
 	va_start(args, format);
-	ret = p_strdup_vprintf(data_stack_pool, format, args);
+	ret = p_strdup_vprintf(unsafe_data_stack_pool, format, args);
 	va_end(args);
 
 	return ret;
@@ -314,7 +314,7 @@
 
 const char *t_strdup_vprintf(const char *format, va_list args)
 {
-	return p_strdup_vprintf(data_stack_pool, format, args);
+	return p_strdup_vprintf(unsafe_data_stack_pool, format, args);
 }
 
 const char *t_strconcat(const char *str1, ...)



More information about the dovecot-cvs mailing list