From 2c61955e3aa384926c02322505e22cb446c333d5 Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Sat, 2 Nov 2024 18:10:25 +0100
Subject: mod_smacks: Destroy timed out session in async context (fixes #1884)

Prevents ASYNC-01 due to storage interactions in a timer.

Also considered modifying mod_c2s to allow passing arbitrary closures
into its runner thread but this seems like a big step away from the
current code for just this module.

Also considered creating a dedicated runner in mod_smacks, but ensuring
continuity across module reloads might be tricky.

We could further improve this in the next major version.
---
 plugins/mod_smacks.lua | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

(limited to 'plugins')

diff --git a/plugins/mod_smacks.lua b/plugins/mod_smacks.lua
index e0a7bbfb..292b7e0b 100644
--- a/plugins/mod_smacks.lua
+++ b/plugins/mod_smacks.lua
@@ -494,14 +494,16 @@ module:hook("pre-resource-unbind", function (event)
 			return
 		end
 
-		session.log("debug", "Destroying session for hibernating too long");
-		session_registry[jid.join(session.username, session.host, session.resumption_token)] = nil;
-		old_session_registry:set(session.username, session.resumption_token,
-			{ h = session.handled_stanza_count; t = os.time() });
-		session.resumption_token = nil;
-		session.resending_unacked = true; -- stop outgoing_stanza_filter from re-queueing anything anymore
-		sessionmanager.destroy_session(session, "Hibernating too long");
-		sessions_expired(1);
+		prosody.main_thread:run(function ()
+			session.log("debug", "Destroying session for hibernating too long");
+			session_registry[jid.join(session.username, session.host, session.resumption_token)] = nil;
+			old_session_registry:set(session.username, session.resumption_token,
+				{ h = session.handled_stanza_count; t = os.time() });
+			session.resumption_token = nil;
+			session.resending_unacked = true; -- stop outgoing_stanza_filter from re-queueing anything anymore
+			sessionmanager.destroy_session(session, "Hibernating too long");
+			sessions_expired(1);
+		end);
 	end);
 	if session.conn then
 		local conn = session.conn;
-- 
cgit v1.2.3