commit 95070f9: [Fix] Fix an old issue with order of destruction race between redis pool and lua

Vsevolod Stakhov vsevolod at rspamd.com
Thu May 25 13:49:03 UTC 2023


Author: Vsevolod Stakhov
Date: 2023-05-25 14:41:30 +0100
URL: https://github.com/rspamd/rspamd/commit/95070f959420a871dff813669f809c345993e5e9

[Fix] Fix an old issue with order of destruction race between redis pool and lua

---
 src/libserver/redis_pool.cxx | 11 ++++++-----
 src/lua/lua_common.c         | 12 ++++++++++++
 src/lua/lua_common.h         |  6 ++++++
 src/lua/lua_redis.c          |  2 +-
 4 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/src/libserver/redis_pool.cxx b/src/libserver/redis_pool.cxx
index 19acaa828..0bbfa55de 100644
--- a/src/libserver/redis_pool.cxx
+++ b/src/libserver/redis_pool.cxx
@@ -244,13 +244,13 @@ public:
 		conns_by_ctx.emplace(ctx, conn);
 	}
 
-	~redis_pool() {
-		/*
-		 * XXX: this will prevent hiredis to unregister connections that
-		 * are already destroyed during redisAsyncFree...
-		 */
+	/* Hack to prevent Redis callbacks to be executed */
+	auto prepare_to_die() -> void
+	{
 		wanna_die = true;
 	}
+
+	~redis_pool() {}
 };
 
 
@@ -612,6 +612,7 @@ rspamd_redis_pool_destroy(void *p)
 {
 	auto *pool = reinterpret_cast<class rspamd::redis_pool *>(p);
 
+	pool->prepare_to_die();
 	delete pool;
 }
 
diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c
index db7e284ee..7f4453c57 100644
--- a/src/lua/lua_common.c
+++ b/src/lua/lua_common.c
@@ -918,6 +918,8 @@ rspamd_lua_wipe_realloc (void *ud,
 extern int luaopen_bit(lua_State *L);
 #endif
 
+static bool lua_initialized = false;
+
 lua_State *
 rspamd_lua_init (bool wipe_mem)
 {
@@ -1039,6 +1041,8 @@ rspamd_lua_init (bool wipe_mem)
 	lua_setglobal (L, "get_traces");
 #endif
 
+	lua_initialized = true;
+
 	return L;
 }
 
@@ -1063,6 +1067,14 @@ rspamd_lua_close (lua_State *L)
 	DL_DELETE(rspamd_lua_global_ctx, ctx);
 	kh_destroy(lua_class_set, ctx->classes);
 	g_free(ctx);
+
+	lua_initialized = false;
+}
+
+bool
+rspamd_lua_is_initialised(void)
+{
+	return lua_initialized;
 }
 
 void
diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h
index b782b3d37..2ea51249d 100644
--- a/src/lua/lua_common.h
+++ b/src/lua/lua_common.h
@@ -647,6 +647,12 @@ gchar *rspamd_lua_get_module_name (lua_State *L);
 bool rspamd_lua_universal_pcall (lua_State *L, gint cbref, const gchar* strloc,
 								 gint nret, const gchar *args, GError **err, ...);
 
+/**
+ * Returns true if lua is initialised
+ * @return
+ */
+bool rspamd_lua_is_initialised(void);
+
 /**
 * Wrapper for lua_geti from lua 5.3
 * @param L
diff --git a/src/lua/lua_redis.c b/src/lua/lua_redis.c
index 8b72a52da..99fc383b5 100644
--- a/src/lua/lua_redis.c
+++ b/src/lua/lua_redis.c
@@ -460,7 +460,7 @@ lua_redis_callback (redisAsyncContext *c, gpointer r, gpointer priv)
 	ctx = sp_ud->ctx;
 	ud = sp_ud->c;
 
-	if (ud->terminated) {
+	if (ud->terminated || !rspamd_lua_is_initialised()) {
 		/* We are already at the termination stage, just go out */
 		return;
 	}


More information about the Commits mailing list