From 2fee108f62519fa22bf4b06eb94373b92e836e18 Mon Sep 17 00:00:00 2001 From: ErrorNoInternet Date: Fri, 28 Feb 2025 23:13:26 -0500 Subject: [PATCH] fix: properly prevent deadlock on container cleanup `ecs` was being locked once in find_entities, and another time when `ContainerRef::close()` called by the garbage collector from table.set. --- src/events.rs | 2 -- src/lua/client/world.rs | 47 +++++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/events.rs b/src/events.rs index 1f8aabe..f37da2b 100644 --- a/src/events.rs +++ b/src/events.rs @@ -14,8 +14,6 @@ use tokio::net::TcpListener; #[allow(clippy::too_many_lines)] pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow::Result<()> { - state.lua.gc_stop(); - match event { Event::AddPlayer(player_info) => { call_listeners(&state, "add_player", Player::from(player_info)).await; diff --git a/src/lua/client/world.rs b/src/lua/client/world.rs index 6f5942f..929f8ea 100644 --- a/src/lua/client/world.rs +++ b/src/lua/client/world.rs @@ -53,11 +53,9 @@ pub async fn find_entities( client: UserDataRef, filter_fn: Function, ) -> Result> { - let mut entities = Vec::new(); - - { + let entities = { let mut ecs = client.ecs.lock(); - let mut query = ecs.query_filtered::<( + ecs.query_filtered::<( &MinecraftEntityId, &EntityUuid, &EntityKind, @@ -65,25 +63,34 @@ pub async fn find_entities( &AzaleaPosition, &LookDirection, &Pose, - ), Without>(); - - for (id, uuid, kind, custom_name, position, direction, pose) in query.iter(&ecs) { - let entity = lua.create_table()?; - entity.set("id", id.0)?; - entity.set("uuid", uuid.to_string())?; - entity.set("kind", kind.to_string())?; - entity.set("custom_name", custom_name.as_ref().map(ToString::to_string))?; - entity.set("position", Vec3::from(position))?; - entity.set("direction", Direction::from(direction))?; - entity.set("pose", *pose as u8)?; - entities.push(entity); - } - } + ), Without>() + .iter(&ecs) + .map(|(id, uuid, kind, custom_name, position, direction, pose)| { + ( + id.0, + uuid.to_string(), + kind.to_string(), + custom_name.as_ref().map(ToString::to_string), + Vec3::from(position), + Direction::from(direction), + *pose as u8, + ) + }) + .collect::>() + }; let mut matched = Vec::new(); - for entity in entities { + for (id, uuid, kind, custom_name, position, direction, pose) in entities { + let entity = lua.create_table()?; + entity.set("id", id)?; + entity.set("uuid", uuid)?; + entity.set("kind", kind)?; + entity.set("custom_name", custom_name)?; + entity.set("position", position)?; + entity.set("direction", direction)?; + entity.set("pose", pose)?; if filter_fn.call_async::(&entity).await? { - matched.push(entity) + matched.push(entity); } } Ok(matched)