From 0c1b3da90d7528e773e520d657a0e9d2318da577 Mon Sep 17 00:00:00 2001 From: "cebka@mailsupport.rambler.ru" Date: Wed, 24 Sep 2008 02:14:18 +0400 Subject: [PATCH] * Rework config file memory allocation to separate memory pool for easy reloading without calling of ~1000 free syscalls * Add memory_pool_alloc0 for initializing newly allocated space in pool with zeroes --- cfg_file.h | 2 ++ cfg_file.y | 35 ++++++++++++++++------------ cfg_utils.c | 66 ++++++++++------------------------------------------- main.c | 14 +++++++----- mem_pool.c | 10 ++++++++ mem_pool.h | 1 + 6 files changed, 53 insertions(+), 75 deletions(-) diff --git a/cfg_file.h b/cfg_file.h index 592a0eb27..6e93a5f44 100644 --- a/cfg_file.h +++ b/cfg_file.h @@ -17,6 +17,7 @@ #include #include #include +#include "mem_pool.h" #include "upstream.h" #include "memcached.h" #include "filter.h" @@ -76,6 +77,7 @@ struct module_opt { }; struct config_file { + memory_pool_t *cfg_pool; char *cfg_name; char *pid_file; char *temp_dir; diff --git a/cfg_file.y b/cfg_file.y index 9ba219614..ae901964b 100644 --- a/cfg_file.y +++ b/cfg_file.y @@ -99,7 +99,8 @@ tempdir : yyerror ("yyparse: \"%s\" is not a directory", $3); YYERROR; } - cfg->temp_dir = $3; + cfg->temp_dir = memory_pool_strdup (cfg->cfg_pool, $3); + free ($3); } ; @@ -139,25 +140,29 @@ bind_cred: header_filters: HEADER_FILTERS EQSIGN QUOTEDSTRING { - cfg->header_filters_str = g_strdup ($3); + cfg->header_filters_str = memory_pool_strdup (cfg->cfg_pool, $3); + free ($3); } ; mime_filters: MIME_FILTERS EQSIGN QUOTEDSTRING { - cfg->mime_filters_str = g_strdup ($3); + cfg->mime_filters_str = memory_pool_strdup (cfg->cfg_pool, $3); + free ($3); } ; message_filters: MESSAGE_FILTERS EQSIGN QUOTEDSTRING { - cfg->message_filters_str = g_strdup ($3); + cfg->message_filters_str = memory_pool_strdup (cfg->cfg_pool, $3); + free ($3); } ; url_filters: URL_FILTERS EQSIGN QUOTEDSTRING { - cfg->url_filters_str = g_strdup ($3); + cfg->url_filters_str = memory_pool_strdup (cfg->cfg_pool, $3); + free ($3); } ; @@ -268,31 +273,31 @@ metriccmd: metricname: NAME EQSIGN QUOTEDSTRING { if (cur_metric == NULL) { - cur_metric = g_malloc (sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); } - cur_metric->name = g_strdup ($3); + cur_metric->name = memory_pool_strdup (cfg->cfg_pool, $3); } ; metricfunction: FUNCTION EQSIGN QUOTEDSTRING { if (cur_metric == NULL) { - cur_metric = g_malloc (sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); } - cur_metric->func_name = g_strdup ($3); + cur_metric->func_name = memory_pool_strdup (cfg->cfg_pool, $3); } ; metricscore: REQUIRED_SCORE EQSIGN NUMBER { if (cur_metric == NULL) { - cur_metric = g_malloc (sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); } cur_metric->required_score = $3; } | REQUIRED_SCORE EQSIGN FRACT { if (cur_metric == NULL) { - cur_metric = g_malloc (sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); } cur_metric->required_score = $3; } @@ -309,12 +314,12 @@ factorsbody: factorparam: QUOTEDSTRING EQSIGN FRACT { - double *tmp = g_malloc (sizeof (double)); + double *tmp = memory_pool_alloc (cfg->cfg_pool, sizeof (double)); *tmp = $3; g_hash_table_insert (cfg->factors, $1, tmp); } | QUOTEDSTRING EQSIGN NUMBER { - double *tmp = g_malloc (sizeof (double)); + double *tmp = memory_pool_alloc (cfg->cfg_pool, sizeof (double)); *tmp = $3; g_hash_table_insert (cfg->factors, $1, tmp); }; @@ -336,7 +341,7 @@ requirecmd: yyerror ("yyparse: cannot stat file %s, %m", $3); YYERROR; } - cur = g_malloc (sizeof (struct perl_module)); + cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct perl_module)); if (cur == NULL) { yyerror ("yyparse: g_malloc: %s", strerror(errno)); YYERROR; @@ -365,7 +370,7 @@ optcmd: cur_module_opt = g_malloc (sizeof (cur_module_opt)); LIST_INIT (cur_module_opt); } - mopt = g_malloc (sizeof (struct module_opt)); + mopt = memory_pool_alloc (cfg->cfg_pool, sizeof (struct module_opt)); mopt->param = $1; mopt->value = $3; LIST_INSERT_HEAD (cur_module_opt, mopt, next); diff --git a/cfg_utils.c b/cfg_utils.c index a2a783cc2..6f290d2d8 100644 --- a/cfg_utils.c +++ b/cfg_utils.c @@ -27,25 +27,6 @@ extern int yylineno; extern char *yytext; -static void -clean_hash_bucket (gpointer key, gpointer value, gpointer unused) -{ - LIST_HEAD (moduleoptq, module_opt) *cur_module_opt = (struct moduleoptq *)value; - struct module_opt *cur, *tmp; - - LIST_FOREACH_SAFE (cur, cur_module_opt, next, tmp) { - if (cur->param) { - free (cur->param); - } - if (cur->value) { - free (cur->value); - } - LIST_REMOVE (cur, next); - free (cur); - } - free (cur_module_opt); -} - int add_memcached_server (struct config_file *cf, char *str) { @@ -160,29 +141,6 @@ init_defaults (struct config_file *cfg) void free_config (struct config_file *cfg) { - if (cfg->pid_file) { - g_free (cfg->pid_file); - } - if (cfg->temp_dir) { - g_free (cfg->temp_dir); - } - if (cfg->bind_host) { - g_free (cfg->bind_host); - } - if (cfg->header_filters_str) { - g_free (cfg->header_filters_str); - } - if (cfg->mime_filters_str) { - g_free (cfg->mime_filters_str); - } - if (cfg->message_filters_str) { - g_free (cfg->message_filters_str); - } - if (cfg->url_filters_str) { - g_free (cfg->url_filters_str); - } - - g_hash_table_foreach (cfg->modules_opts, clean_hash_bucket, NULL); g_hash_table_remove_all (cfg->modules_opts); g_hash_table_unref (cfg->modules_opts); g_hash_table_remove_all (cfg->variables); @@ -193,6 +151,7 @@ free_config (struct config_file *cfg) g_hash_table_unref (cfg->factors); g_hash_table_remove_all (cfg->c_modules); g_hash_table_unref (cfg->c_modules); + memory_pool_delete (cfg->cfg_pool); } char* @@ -321,11 +280,10 @@ substitute_variable (struct config_file *cfg, char *str, u_char recursive) var = substitute_variable (cfg, var, recursive); } /* Allocate new string */ - new = g_malloc (len - strlen (v_begin) + strlen (var) + 1); + new = memory_pool_alloc (cfg->cfg_pool, len - strlen (v_begin) + strlen (var) + 1); snprintf (new, len - strlen (v_begin) + strlen (var) + 1, "%s%s%s", str, var, v_end + 1); - g_free (str); str = new; } @@ -375,23 +333,23 @@ parse_filters_str (struct config_file *cfg, const char *str, enum script_type ty /* Search modules from known C modules */ for (i = 0; i < MODULES_NUM; i++) { if (strcasecmp (modules[i].name, *p) == 0) { - cur = g_malloc (sizeof (struct filter)); + cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct filter)); cur->type = C_FILTER; switch (type) { case SCRIPT_HEADER: - cur->func_name = g_strdup (*p); + cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); LIST_INSERT_HEAD (&cfg->header_filters, cur, next); break; case SCRIPT_MIME: - cur->func_name = g_strdup (*p); + cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); LIST_INSERT_HEAD (&cfg->mime_filters, cur, next); break; case SCRIPT_MESSAGE: - cur->func_name = g_strdup (*p); + cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); LIST_INSERT_HEAD (&cfg->message_filters, cur, next); break; case SCRIPT_URL: - cur->func_name = g_strdup (*p); + cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); LIST_INSERT_HEAD (&cfg->url_filters, cur, next); break; } @@ -402,23 +360,23 @@ parse_filters_str (struct config_file *cfg, const char *str, enum script_type ty /* Go to next iteration */ continue; } - cur = g_malloc (sizeof (struct filter)); + cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct filter)); cur->type = PERL_FILTER; switch (type) { case SCRIPT_HEADER: - cur->func_name = g_strdup (*p); + cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); LIST_INSERT_HEAD (&cfg->header_filters, cur, next); break; case SCRIPT_MIME: - cur->func_name = g_strdup (*p); + cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); LIST_INSERT_HEAD (&cfg->mime_filters, cur, next); break; case SCRIPT_MESSAGE: - cur->func_name = g_strdup (*p); + cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); LIST_INSERT_HEAD (&cfg->message_filters, cur, next); break; case SCRIPT_URL: - cur->func_name = g_strdup (*p); + cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); LIST_INSERT_HEAD (&cfg->url_filters, cur, next); break; } diff --git a/main.c b/main.c index c67ce419f..5c9fe7909 100644 --- a/main.c +++ b/main.c @@ -96,8 +96,9 @@ fork_worker (struct rspamd_main *rspamd, int listen_sock, int reconfig, enum pro if (reconfig) { tmp_cfg = (struct config_file *) g_malloc (sizeof (struct config_file)); if (tmp_cfg) { - cfg_file = strdup (rspamd->cfg->cfg_name); bzero (tmp_cfg, sizeof (struct config_file)); + tmp_cfg->cfg_pool = memory_pool_new (32768); + cfg_file = memory_pool_strdup (tmp_cfg->cfg_pool, rspamd->cfg->cfg_name); f = fopen (rspamd->cfg->cfg_name , "r"); if (f == NULL) { msg_warn ("fork_worker: cannot open file: %s", rspamd->cfg->cfg_name ); @@ -177,11 +178,12 @@ main (int argc, char **argv) active_worker = NULL; bzero (rspamd->cfg, sizeof (struct config_file)); + rspamd->cfg->cfg_pool = memory_pool_new (32768); init_defaults (rspamd->cfg); bzero (&signals, sizeof (struct sigaction)); - rspamd->cfg->cfg_name = strdup (FIXED_CONFIG_FILE); + rspamd->cfg->cfg_name = memory_pool_strdup (rspamd->cfg->cfg_pool, FIXED_CONFIG_FILE); read_cmd_line (argc, argv, rspamd->cfg); msg_warn ("(main) starting..."); @@ -203,15 +205,15 @@ main (int argc, char **argv) } fclose (f); - rspamd->cfg->cfg_name = strdup (rspamd->cfg->cfg_name ); + rspamd->cfg->cfg_name = memory_pool_strdup (rspamd->cfg->cfg_pool, rspamd->cfg->cfg_name ); /* Strictly set temp dir */ if (!rspamd->cfg->temp_dir) { msg_warn ("tempdir is not set, trying to use $TMPDIR"); - rspamd->cfg->temp_dir = getenv ("TMPDIR"); + rspamd->cfg->temp_dir = memory_pool_strdup (rspamd->cfg->cfg_pool, getenv ("TMPDIR")); if (!rspamd->cfg->temp_dir) { - rspamd->cfg->temp_dir = strdup ("/tmp"); + rspamd->cfg->temp_dir = memory_pool_strdup (rspamd->cfg->cfg_pool, "/tmp"); } } @@ -227,7 +229,7 @@ main (int argc, char **argv) /* Init C modules */ for (i = 0; i < MODULES_NUM; i ++) { - cur_module = g_malloc (sizeof (struct module_ctx)); + cur_module = memory_pool_alloc (rspamd->cfg->cfg_pool, sizeof (struct module_ctx)); if (modules[i].module_init_func(cfg, &cur_module) == 0) { g_hash_table_insert (cfg->c_modules, (gpointer)modules[i].name, cur_module); } diff --git a/mem_pool.c b/mem_pool.c index e32d58f31..fc14af790 100644 --- a/mem_pool.c +++ b/mem_pool.c @@ -85,6 +85,16 @@ memory_pool_alloc (memory_pool_t *pool, size_t size) return NULL; } +void * +memory_pool_alloc0 (memory_pool_t *pool, size_t size) +{ + void *pointer = memory_pool_alloc (pool, size); + if (pointer) { + bzero (pointer, size); + } + return pointer; +} + char * memory_pool_strdup (memory_pool_t *pool, const char *src) { diff --git a/mem_pool.h b/mem_pool.h index 1e2c020ca..f5d3e4238 100644 --- a/mem_pool.h +++ b/mem_pool.h @@ -22,6 +22,7 @@ typedef struct memory_pool_stat_s { memory_pool_t* memory_pool_new (size_t size); void* memory_pool_alloc (memory_pool_t* pool, size_t size); +void* memory_pool_alloc0 (memory_pool_t* pool, size_t size); char* memory_pool_strdup (memory_pool_t* pool, const char *src); void memory_pool_delete (memory_pool_t* pool); -- 2.39.5