]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Another try to fix race conditions on config unload
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 10 Sep 2018 15:27:37 +0000 (16:27 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 10 Sep 2018 15:28:08 +0000 (16:28 +0100)
src/libserver/cfg_utils.c
src/libutil/mem_pool.c
src/libutil/mem_pool.h

index 016556912253f9697bef0d4bf5b41d2396e15794..f4f9393bf2bac517fcfa95f092ecf17fab757fc5 100644 (file)
@@ -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);
 }
 
index e6941c8f780ffbf01a5a6564348078e0c6dbfe06..322ebc409e0c38d29164475897652ee8d1eeab37 100644 (file)
@@ -656,6 +656,27 @@ rspamd_mempool_adjust_entry (struct rspamd_mempool_entry_point *e)
        memset (e->elts, 0, sizeof (e->elts));
 }
 
+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)
 {
@@ -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 &&
index 27d4c8ebfcda2d935b2472398dce107e453daebf..c8dbf6042e013383c87abaecb7ca90f116fdb338 100644 (file)
@@ -223,6 +223,13 @@ void rspamd_mempool_add_destructor_full (rspamd_mempool_t *pool,
 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