Fix deadlock when handling incoming RPC messages

We need to drop the lock on the rpc::ClientState when handling an incoming messages in case those message handlers attempt to interact with the client and grab the lock.
This commit is contained in:
Nathan Sobo 2021-09-17 16:12:03 -07:00
parent 42bf88b52a
commit 9a9c8aec3f

View file

@ -371,11 +371,11 @@ impl Client {
if let Some(extract_entity_id) =
state.entity_id_extractors.get(&message.payload_type_id())
{
let payload_type_id = message.payload_type_id();
let entity_id = (extract_entity_id)(message.as_ref());
if let Some(handler) = state
.model_handlers
.get_mut(&(message.payload_type_id(), entity_id))
{
let handler_key = (payload_type_id, entity_id);
if let Some(mut handler) = state.model_handlers.remove(&handler_key) {
drop(state); // Avoid deadlocks if the handler interacts with rpc::Client
let start_time = Instant::now();
log::info!("RPC client message {}", message.payload_type_name());
(handler)(message, &mut cx);
@ -383,6 +383,10 @@ impl Client {
"RPC message handled. duration:{:?}",
start_time.elapsed()
);
this.state
.write()
.model_handlers
.insert(handler_key, handler);
} else {
log::info!("unhandled message {}", message.payload_type_name());
}