if (s->blacklist) {
g_hash_table_destroy (s->blacklist);
}
- g_free (s);
+ g_slice_free1 (sizeof (struct rspamd_settings), s);
+}
+
+static struct rspamd_settings *
+settings_ref (struct rspamd_settings *s)
+{
+ if (s == NULL) {
+ s = g_slice_alloc (sizeof (struct rspamd_settings));
+ s->metric_scores = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ s->reject_scores = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ s->metric_actions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, settings_actions_free);
+ s->factors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ s->whitelist = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ s->blacklist = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ s->statfile_alias = NULL;
+ s->want_spam = FALSE;
+ s->ref_count = 1;
+ }
+ else {
+ s->ref_count ++;
+ }
+
+ return s;
+}
+
+static void
+settings_unref (struct rspamd_settings *s)
+{
+ if (s != NULL) {
+ s->ref_count --;
+ if (s->ref_count <= 0) {
+ settings_free (s);
+ }
+ }
}
struct metric_action *new_act;
struct rspamd_settings *cur_settings;
GList *cur_act;
- gchar *cur_name;
+ gchar *cur_name;
void *json_it;
double *score;
nelts = json_array_size (js);
for (i = 0; i < nelts; i++) {
- cur_settings = g_malloc (sizeof (struct rspamd_settings));
- cur_settings->metric_scores = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- cur_settings->reject_scores = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- cur_settings->metric_actions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, settings_actions_free);
- cur_settings->factors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- cur_settings->whitelist = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- cur_settings->blacklist = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- cur_settings->statfile_alias = NULL;
- cur_settings->want_spam = FALSE;
+ cur_settings = settings_ref (NULL);
cur_elt = json_array_get (js, i);
if (!cur_elt || !json_is_object (cur_elt)) {
json_decref (js);
msg_err ("loaded json is not an object");
+ settings_unref (cur_settings);
return;
}
cur_nm = json_object_get (cur_elt, "name");
if (cur_nm == NULL || !json_is_string (cur_nm)) {
json_decref (js);
msg_err ("name is not a string or not exists");
+ settings_unref (cur_settings);
return;
}
cur_name = g_strdup (json_string_value (cur_nm));
cur_settings->want_spam = TRUE;
}
}
- g_hash_table_insert (((struct json_buf *)data->cur_data)->table, cur_name, cur_settings);
+ g_hash_table_replace (((struct json_buf *)data->cur_data)->table, cur_name, cur_settings);
}
json_decref (js);
}
void
init_settings (struct config_file *cfg)
{
- cfg->domain_settings = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, g_free, settings_free);
- cfg->user_settings = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, g_free, settings_free);
+ cfg->domain_settings = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal,
+ g_free, (GDestroyNotify)settings_unref);
+ cfg->user_settings = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal,
+ g_free, (GDestroyNotify)settings_unref);
}
static gboolean
if (check_setting (task, &us, &ds)) {
if (us != NULL || ds != NULL) {
if (us != NULL) {
- g_hash_table_ref (task->cfg->user_settings);
- res->user_settings = us;
- memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_hash_table_unref,
- task->cfg->user_settings);
+ res->user_settings = settings_ref (us);
+ memory_pool_add_destructor (task->task_pool, (pool_destruct_func)settings_unref,
+ us);
}
if (ds != NULL) {
/* Need to ref hash table to avoid occasional data corruption */
- g_hash_table_ref (task->cfg->domain_settings);
- res->domain_settings = ds;
- memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_hash_table_unref,
- task->cfg->domain_settings);
+ res->domain_settings = settings_ref (ds);
+ memory_pool_add_destructor (task->task_pool, (pool_destruct_func)settings_unref,
+ ds);
}
}
else {