dovecot-2.0: Memory leak fixes.

dovecot at dovecot.org dovecot at dovecot.org
Sat Sep 5 01:10:26 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/8ad868df4649
changeset: 9881:8ad868df4649
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Sep 04 18:10:19 2009 -0400
description:
Memory leak fixes.

diffstat:

8 files changed, 55 insertions(+), 28 deletions(-)
src/config/config-filter.c         |   16 ++++++++++++++--
src/config/config-filter.h         |    5 +++--
src/config/config-parser.c         |   26 +++++++++++++++-----------
src/config/config-request.c        |   20 ++++++++++++--------
src/config/doveconf.c              |    2 ++
src/config/main.c                  |    2 ++
src/lib-master/master-service.c    |    1 +
src/lib-settings/settings-parser.c |   11 ++++++-----

diffs (244 lines):

diff -r cce684dfe3e7 -r 8ad868df4649 src/config/config-filter.c
--- a/src/config/config-filter.c	Fri Sep 04 17:34:18 2009 -0400
+++ b/src/config/config-filter.c	Fri Sep 04 18:10:19 2009 -0400
@@ -69,9 +69,12 @@ void config_filter_deinit(struct config_
 void config_filter_deinit(struct config_filter_context **_ctx)
 {
 	struct config_filter_context *ctx = *_ctx;
+	unsigned int i;
 
 	*_ctx = NULL;
 
+	for (i = 0; ctx->parsers[i] != NULL; i++)
+		config_filter_parsers_free(ctx->parsers[i]->parsers);
 	pool_unref(&ctx->pool);
 }
 
@@ -158,9 +161,9 @@ config_module_parser_apply_changes(struc
 	return 0;
 }
 
-int config_filter_get_parsers(struct config_filter_context *ctx, pool_t pool,
+int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool,
 			      const struct config_filter *filter,
-			      const struct config_module_parser **parsers_r,
+			      struct config_module_parser **parsers_r,
 			      const char **error_r)
 {
 	struct config_filter_parser *const *src;
@@ -190,6 +193,7 @@ int config_filter_get_parsers(struct con
 
 		if (config_module_parser_apply_changes(dest, src[i], pool,
 						       error_p) < 0) {
+			config_filter_parsers_free(dest);
 			*error_r = error;
 			return -1;
 		}
@@ -197,3 +201,11 @@ int config_filter_get_parsers(struct con
 	*parsers_r = dest;
 	return 0;
 }
+
+void config_filter_parsers_free(struct config_module_parser *parsers)
+{
+	unsigned int i;
+
+	for (i = 0; parsers[i].module_name != NULL; i++)
+		settings_parser_deinit(&parsers[i].parser);
+}
diff -r cce684dfe3e7 -r 8ad868df4649 src/config/config-filter.h
--- a/src/config/config-filter.h	Fri Sep 04 17:34:18 2009 -0400
+++ b/src/config/config-filter.h	Fri Sep 04 18:10:19 2009 -0400
@@ -25,10 +25,11 @@ void config_filter_add_all(struct config
 			   struct config_filter_parser *const *parsers);
 
 /* Build new parsers from all existing ones matching the given filter. */
-int config_filter_get_parsers(struct config_filter_context *ctx, pool_t pool,
+int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool,
 			      const struct config_filter *filter,
-			      const struct config_module_parser **parsers_r,
+			      struct config_module_parser **parsers_r,
 			      const char **error_r);
+void config_filter_parsers_free(struct config_module_parser *parsers);
 
 /* Returns TRUE if filter matches mask. */
 bool config_filter_match(const struct config_filter *mask,
diff -r cce684dfe3e7 -r 8ad868df4649 src/config/config-parser.c
--- a/src/config/config-parser.c	Fri Sep 04 17:34:18 2009 -0400
+++ b/src/config/config-parser.c	Fri Sep 04 18:10:19 2009 -0400
@@ -273,25 +273,29 @@ config_all_parsers_check(struct parser_c
 			 const char **error_r)
 {
 	struct config_filter_parser *const *parsers;
-	const struct config_module_parser *tmp_parsers;
+	struct config_module_parser *tmp_parsers;
 	unsigned int i, count;
 	pool_t tmp_pool;
+	int ret = 0;
 
 	tmp_pool = pool_alloconly_create("config parsers check", 1024*32);
 	parsers = array_get(&ctx->all_parsers, &count);
 	i_assert(count > 0 && parsers[count-1] == NULL);
 	count--;
-	for (i = 0; i < count; i++) {
+	for (i = 0; i < count && ret == 0; i++) {
+		if (config_filter_parsers_get(new_filter, tmp_pool,
+					      &parsers[i]->filter,
+					      &tmp_parsers, error_r) < 0) {
+			ret = -1;
+			break;
+		}
+
+		ret = config_filter_parser_check(ctx, tmp_parsers, error_r);
+		config_filter_parsers_free(tmp_parsers);
 		p_clear(tmp_pool);
-		if (config_filter_get_parsers(new_filter, tmp_pool,
-					      &parsers[i]->filter,
-					      &tmp_parsers, error_r) < 0)
-			break;
-
-		if (config_filter_parser_check(ctx, tmp_parsers, error_r) < 0)
-			break;
-	}
-	return i == count ? 0 : -1;
+	}
+	pool_unref(&tmp_pool);
+	return ret;
 }
 
 static int
diff -r cce684dfe3e7 -r 8ad868df4649 src/config/config-request.c
--- a/src/config/config-request.c	Fri Sep 04 17:34:18 2009 -0400
+++ b/src/config/config-request.c	Fri Sep 04 18:10:19 2009 -0400
@@ -236,16 +236,17 @@ int config_request_handle(const struct c
 			  bool check_settings,
 			  config_request_callback_t *callback, void *context)
 {
-	const struct config_module_parser *l;
+	struct config_module_parser *parsers, *parser;
 	struct settings_export_context ctx;
 	const char *error;
+	unsigned int i;
 	int ret = 0;
 
 	memset(&ctx, 0, sizeof(ctx));
 	ctx.pool = pool_alloconly_create("config request", 1024*16);
 
-	if (config_filter_get_parsers(config_filter, ctx.pool, filter,
-				      &l, &error) < 0) {
+	if (config_filter_parsers_get(config_filter, ctx.pool, filter,
+				      &parsers, &error) < 0) {
 		i_error("%s", error);
 		pool_unref(&ctx.pool);
 		return -1;
@@ -259,16 +260,18 @@ int config_request_handle(const struct c
 	ctx.keys = hash_table_create(default_pool, ctx.pool, 0,
 				     str_hash, (hash_cmp_callback_t *)strcmp);
 
-	for (; l->module_name != NULL; l++) {
+	for (i = 0; parsers[i].module_name != NULL; i++) {
+		parser = &parsers[i];
 		if (*module != '\0' &&
-		    !config_module_parser_is_in_service(l, module))
+		    !config_module_parser_is_in_service(parser, module))
 			continue;
 
-		settings_export(&ctx, l->root, settings_parser_get(l->parser),
-				settings_parser_get_changes(l->parser));
+		settings_export(&ctx, parser->root,
+				settings_parser_get(parser->parser),
+				settings_parser_get_changes(parser->parser));
 
 		if (check_settings) {
-			if (!settings_parser_check(l->parser, ctx.pool,
+			if (!settings_parser_check(parser->parser, ctx.pool,
 						   &error)) {
 				i_error("%s", error);
 				ret = -1;
@@ -276,6 +279,7 @@ int config_request_handle(const struct c
 			}
 		}
 	}
+	config_filter_parsers_free(parsers);
 	hash_table_destroy(&ctx.keys);
 	pool_unref(&ctx.pool);
 	return ret;
diff -r cce684dfe3e7 -r 8ad868df4649 src/config/doveconf.c
--- a/src/config/doveconf.c	Fri Sep 04 17:34:18 2009 -0400
+++ b/src/config/doveconf.c	Fri Sep 04 18:10:19 2009 -0400
@@ -168,6 +168,7 @@ static void config_dump_human(const stru
 	o_stream_cork(output);
 	config_connection_request_human(output, filter, module, scope);
 	o_stream_uncork(output);
+	o_stream_unref(&output);
 }
 
 static void config_request_putenv(const char *key, const char *value,
@@ -297,6 +298,7 @@ int main(int argc, char *argv[])
 		execvp(exec_args[0], exec_args);
 		i_fatal("execvp(%s) failed: %m", exec_args[0]);
 	}
+	config_filter_deinit(&config_filter);
 	master_service_deinit(&master_service);
         return 0;
 }
diff -r cce684dfe3e7 -r 8ad868df4649 src/config/main.c
--- a/src/config/main.c	Fri Sep 04 17:34:18 2009 -0400
+++ b/src/config/main.c	Fri Sep 04 18:10:19 2009 -0400
@@ -36,6 +36,8 @@ int main(int argc, char *argv[])
 
 	master_service_run(master_service, client_connected);
 	config_connections_destroy_all();
+
+	config_filter_deinit(&config_filter);
 	master_service_deinit(&master_service);
         return 0;
 }
diff -r cce684dfe3e7 -r 8ad868df4649 src/lib-master/master-service.c
--- a/src/lib-master/master-service.c	Fri Sep 04 17:34:18 2009 -0400
+++ b/src/lib-master/master-service.c	Fri Sep 04 18:10:19 2009 -0400
@@ -488,6 +488,7 @@ void master_service_deinit(struct master
 	lib_signals_deinit();
 	io_loop_destroy(&service->ioloop);
 
+	i_free(service->listeners);
 	i_free(service->name);
 	i_free(service);
 
diff -r cce684dfe3e7 -r 8ad868df4649 src/lib-settings/settings-parser.c
--- a/src/lib-settings/settings-parser.c	Fri Sep 04 17:34:18 2009 -0400
+++ b/src/lib-settings/settings-parser.c	Fri Sep 04 18:10:19 2009 -0400
@@ -118,7 +118,6 @@ settings_parser_init_list(pool_t set_poo
 
 	i_assert(count > 0);
 
-	pool_ref(set_pool);
 	parser_pool = pool_alloconly_create("settings parser", 16384);
 	ctx = p_new(parser_pool, struct setting_parser_context, 1);
 	ctx->set_pool = set_pool;
@@ -1184,19 +1183,21 @@ settings_parser_dup(struct setting_parse
 	struct hash_table *links;
 	void *key, *value;
 	unsigned int i;
+	pool_t parser_pool;
 
 	pool_ref(new_pool);
-	new_ctx = p_new(new_pool, struct setting_parser_context, 1);
+	parser_pool = pool_alloconly_create("dup settings parser", 8192);
+	new_ctx = p_new(parser_pool, struct setting_parser_context, 1);
 	new_ctx->set_pool = new_pool;
-	new_ctx->parser_pool =
-		pool_alloconly_create("dup settings parser", 8192);
+	new_ctx->parser_pool = parser_pool;
 	new_ctx->flags = old_ctx->flags;
 	new_ctx->str_vars_are_expanded = old_ctx->str_vars_are_expanded;
 	new_ctx->linenum = old_ctx->linenum;
 	new_ctx->error = p_strdup(new_ctx->parser_pool, old_ctx->error);
 	new_ctx->prev_info = old_ctx->prev_info;
 
-	links = hash_table_create(default_pool, default_pool, 0, NULL, NULL);
+	links = hash_table_create(default_pool, new_ctx->parser_pool,
+				  0, NULL, NULL);
 
 	new_ctx->root_count = old_ctx->root_count;
 	new_ctx->roots = p_new(new_ctx->parser_pool, struct setting_link,


More information about the dovecot-cvs mailing list