From 938b3d28258fdab4ef4754768af131004e99bc30 Mon Sep 17 00:00:00 2001 From: Jade Ellis Date: Mon, 12 Oct 2026 17:49:39 +0100 Subject: [PATCH] refactor(admin): Release handle lock before command execution Change admin service handle to SyncRwLock and copy the handler function pointer before awaiting execution to prevent deadlock. --- src/admin/mod.rs | 12 ++++-------- src/router/run.rs | 4 ++-- src/service/admin/mod.rs | 12 +++++++----- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/admin/mod.rs b/src/admin/mod.rs index fd73c3f15..6c4a421cc 100644 --- a/src/admin/mod.rs +++ b/src/admin/mod.rs @@ -39,17 +39,13 @@ conduwuit::mod_dtor! {} pub use crate::admin::AdminCommand; /// Install the admin command processor -pub async fn init(admin_service: &service::admin::Service) { +pub fn init(admin_service: &service::admin::Service) { _ = admin_service.complete.write().insert(processor::complete); - _ = admin_service - .handle - .write() - .await - .insert(processor::dispatch); + _ = admin_service.handle.write().insert(processor::dispatch); } /// Uninstall the admin command handler -pub async fn fini(admin_service: &service::admin::Service) { - _ = admin_service.handle.write().await.take(); +pub fn fini(admin_service: &service::admin::Service) { + _ = admin_service.handle.write().take(); _ = admin_service.complete.write().take(); } diff --git a/src/router/run.rs b/src/router/run.rs index bff30367a..f5a2ebb2f 100644 --- a/src/router/run.rs +++ b/src/router/run.rs @@ -25,7 +25,7 @@ pub(crate) async fn run(services: Arc) -> Result<()> { debug!("Start"); // Install the admin room callback here for now - admin::init(&services.admin).await; + admin::init(&services.admin); // Setup shutdown/signal handling let handle = ServerHandle::new(); @@ -60,7 +60,7 @@ pub(crate) async fn run(services: Arc) -> Result<()> { _ = sigs.await; // Remove the admin room callback - admin::fini(&services.admin).await; + admin::fini(&services.admin); debug_info!("Finish"); res diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index 15dc33d50..923c2f15c 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -27,7 +27,6 @@ use ruma::{ }, }, }; -use tokio::sync::RwLock; use crate::{ Dep, account_data, config, globals, @@ -38,7 +37,7 @@ use crate::{ pub struct Service { services: Services, channel: (Sender, Receiver), - pub handle: RwLock>, + pub handle: SyncRwLock>, pub complete: SyncRwLock>, #[cfg(feature = "console")] pub console: Arc, @@ -131,7 +130,7 @@ impl crate::Service for Service { media: args.depend::("media"), }, channel: loole::bounded(COMMAND_QUEUE_LIMIT), - handle: RwLock::new(None), + handle: SyncRwLock::new(None), complete: SyncRwLock::new(None), #[cfg(feature = "console")] console: console::Console::new(&args), @@ -372,8 +371,11 @@ impl Service { } async fn process_command(&self, command: CommandInput) -> ProcessorResult { - let handle_guard = self.handle.read().await; - let handle = handle_guard.as_ref().expect("Admin module is not loaded"); + let handle = *self + .handle + .read() + .as_ref() + .expect("Admin module is not loaded"); let services = self .services