aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-09-10 16:27:37 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-09-10 16:28:08 +0100
commit86e0d6c14dde85306c7053d2ddac7624c3af21e1 (patch)
tree83ac7a1b6f0d2ade05f2674667d3bab2a166b32f /src
parent583ea41541514ef72e454aebfc05df9aa0d75fb4 (diff)
downloadrspamd-86e0d6c14dde85306c7053d2ddac7624c3af21e1.tar.gz
rspamd-86e0d6c14dde85306c7053d2ddac7624c3af21e1.zip
[Fix] Another try to fix race conditions on config unload
Diffstat (limited to 'src')
-rw-r--r--src/libserver/cfg_utils.c32
-rw-r--r--src/libutil/mem_pool.c22
-rw-r--r--src/libutil/mem_pool.h7
3 files changed, 45 insertions, 16 deletions
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 016556912..f4f9393bf 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -213,8 +213,6 @@ rspamd_config_free (struct rspamd_config *cfg)
struct rspamd_config_post_load_script *sc, *sctmp;
struct rspamd_worker_log_pipe *lp, *ltmp;
- rspamd_map_remove_all (cfg);
-
DL_FOREACH_SAFE (cfg->finish_callbacks, sc, sctmp) {
luaL_unref (cfg->lua_state, LUA_REGISTRYINDEX, sc->cbref);
g_free (sc);
@@ -225,18 +223,12 @@ rspamd_config_free (struct rspamd_config *cfg)
g_free (sc);
}
- if (cfg->monitored_ctx) {
- rspamd_monitored_ctx_destroy (cfg->monitored_ctx);
- }
+ rspamd_map_remove_all (cfg);
+ rspamd_mempool_destructors_enforce (cfg->cfg_pool);
g_list_free (cfg->classifiers);
g_list_free (cfg->workers);
rspamd_symbols_cache_destroy (cfg->cache);
-#ifdef WITH_HIREDIS
- if (cfg->redis_pool) {
- rspamd_redis_pool_destroy (cfg->redis_pool);
- }
-#endif
ucl_object_unref (cfg->rcl_obj);
ucl_object_unref (cfg->config_comments);
ucl_object_unref (cfg->doc_strings);
@@ -251,19 +243,28 @@ rspamd_config_free (struct rspamd_config *cfg)
g_hash_table_unref (cfg->wrk_parsers);
g_hash_table_unref (cfg->trusted_keys);
- if (cfg->checksum) {
- g_free (cfg->checksum);
- }
-
rspamd_re_cache_unref (cfg->re_cache);
rspamd_upstreams_library_unref (cfg->ups_ctx);
- rspamd_mempool_delete (cfg->cfg_pool);
g_ptr_array_free (cfg->c_modules, TRUE);
if (cfg->lua_state && cfg->own_lua_state) {
lua_thread_pool_free (cfg->lua_thread_pool);
lua_close (cfg->lua_state);
}
+
+#ifdef WITH_HIREDIS
+ if (cfg->redis_pool) {
+ rspamd_redis_pool_destroy (cfg->redis_pool);
+ }
+#endif
+
+ if (cfg->monitored_ctx) {
+ rspamd_monitored_ctx_destroy (cfg->monitored_ctx);
+ }
+ if (cfg->checksum) {
+ g_free (cfg->checksum);
+ }
+
REF_RELEASE (cfg->libs_ctx);
DL_FOREACH_SAFE (cfg->log_pipes, lp, ltmp) {
@@ -271,6 +272,7 @@ rspamd_config_free (struct rspamd_config *cfg)
g_free (lp);
}
+ rspamd_mempool_delete (cfg->cfg_pool);
g_free (cfg);
}
diff --git a/src/libutil/mem_pool.c b/src/libutil/mem_pool.c
index e6941c8f7..322ebc409 100644
--- a/src/libutil/mem_pool.c
+++ b/src/libutil/mem_pool.c
@@ -657,6 +657,27 @@ rspamd_mempool_adjust_entry (struct rspamd_mempool_entry_point *e)
}
void
+rspamd_mempool_destructors_enforce (rspamd_mempool_t *pool)
+{
+ struct _pool_destructors *destructor;
+ guint i;
+
+ POOL_MTX_LOCK ();
+
+ for (i = 0; i < pool->destructors->len; i ++) {
+ destructor = &g_array_index (pool->destructors, struct _pool_destructors, i);
+ /* Avoid calling destructors for NULL pointers */
+ if (destructor->data != NULL) {
+ destructor->func (destructor->data);
+ }
+ }
+
+ pool->destructors->len = 0;
+
+ POOL_MTX_UNLOCK ();
+}
+
+void
rspamd_mempool_delete (rspamd_mempool_t * pool)
{
struct _pool_chain *cur;
@@ -667,7 +688,6 @@ rspamd_mempool_delete (rspamd_mempool_t * pool)
POOL_MTX_LOCK ();
- /* Find free space in pool chain */
cur = NULL;
if (pool->pools[RSPAMD_MEMPOOL_NORMAL] != NULL &&
diff --git a/src/libutil/mem_pool.h b/src/libutil/mem_pool.h
index 27d4c8ebf..c8dbf6042 100644
--- a/src/libutil/mem_pool.h
+++ b/src/libutil/mem_pool.h
@@ -224,6 +224,13 @@ void rspamd_mempool_replace_destructor (rspamd_mempool_t *pool,
rspamd_mempool_destruct_t func, void *old_data, void *new_data);
/**
+ * Calls all destructors associated with the specific memory pool without removing
+ * of the pool itself
+ * @param pool
+ */
+void rspamd_mempool_destructors_enforce (rspamd_mempool_t *pool);
+
+/**
* Delete pool, free all its chunks and call destructors chain
* @param pool memory pool object
*/