From 0b79950510452ba48c760c9023e803c01b10e4df Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 1 Nov 2022 19:16:02 +0100 Subject: [PATCH] Don't hold the lock while yielding back to the executor in `Client` --- crates/client/src/client.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index c4a3167f83..b03c183881 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -835,11 +835,14 @@ impl Client { continue; }; - if let Some(handler) = state.message_handlers.get(&payload_type_id).cloned() - { - drop(state); // Avoid deadlocks if the handler interacts with rpc::Client - let future = handler(model, message, &this, cx.clone()); + let handler = state.message_handlers.get(&payload_type_id).cloned(); + // Dropping the state prevents deadlocks if the handler interacts with rpc::Client. + // It also ensures we don't hold the lock while yielding back to the executor, as + // that might cause the executor thread driving this future to block indefinitely. + drop(state); + if let Some(handler) = handler { + let future = handler(model, message, &this, cx.clone()); let client_id = this.id; log::debug!( "rpc message received. client_id:{}, message_id:{}, sender_id:{:?}, type:{}",