diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-09-10 16:27:37 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-09-10 16:28:08 +0100 |
commit | 86e0d6c14dde85306c7053d2ddac7624c3af21e1 (patch) | |
tree | 83ac7a1b6f0d2ade05f2674667d3bab2a166b32f | |
parent | 583ea41541514ef72e454aebfc05df9aa0d75fb4 (diff) | |
download | rspamd-86e0d6c14dde85306c7053d2ddac7624c3af21e1.tar.gz rspamd-86e0d6c14dde85306c7053d2ddac7624c3af21e1.zip |
[Fix] Another try to fix race conditions on config unload
-rw-r--r-- | src/libserver/cfg_utils.c | 32 | ||||
-rw-r--r-- | src/libutil/mem_pool.c | 22 | ||||
-rw-r--r-- | src/libutil/mem_pool.h | 7 |
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 */ |