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.
This commit is contained in:
Ryan 2025-02-28 23:13:26 -05:00
parent 88141d74e7
commit 2fee108f62
Signed by: ErrorNoInternet
GPG Key ID: 2486BFB7B1E6A4A3
2 changed files with 27 additions and 22 deletions

View File

@ -14,8 +14,6 @@ use tokio::net::TcpListener;
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow::Result<()> { pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow::Result<()> {
state.lua.gc_stop();
match event { match event {
Event::AddPlayer(player_info) => { Event::AddPlayer(player_info) => {
call_listeners(&state, "add_player", Player::from(player_info)).await; call_listeners(&state, "add_player", Player::from(player_info)).await;

View File

@ -53,11 +53,9 @@ pub async fn find_entities(
client: UserDataRef<Client>, client: UserDataRef<Client>,
filter_fn: Function, filter_fn: Function,
) -> Result<Vec<Table>> { ) -> Result<Vec<Table>> {
let mut entities = Vec::new(); let entities = {
{
let mut ecs = client.ecs.lock(); let mut ecs = client.ecs.lock();
let mut query = ecs.query_filtered::<( ecs.query_filtered::<(
&MinecraftEntityId, &MinecraftEntityId,
&EntityUuid, &EntityUuid,
&EntityKind, &EntityKind,
@ -65,25 +63,34 @@ pub async fn find_entities(
&AzaleaPosition, &AzaleaPosition,
&LookDirection, &LookDirection,
&Pose, &Pose,
), Without<Dead>>(); ), Without<Dead>>()
.iter(&ecs)
for (id, uuid, kind, custom_name, position, direction, pose) in query.iter(&ecs) { .map(|(id, uuid, kind, custom_name, position, direction, pose)| {
let entity = lua.create_table()?; (
entity.set("id", id.0)?; id.0,
entity.set("uuid", uuid.to_string())?; uuid.to_string(),
entity.set("kind", kind.to_string())?; kind.to_string(),
entity.set("custom_name", custom_name.as_ref().map(ToString::to_string))?; custom_name.as_ref().map(ToString::to_string),
entity.set("position", Vec3::from(position))?; Vec3::from(position),
entity.set("direction", Direction::from(direction))?; Direction::from(direction),
entity.set("pose", *pose as u8)?; *pose as u8,
entities.push(entity); )
} })
} .collect::<Vec<_>>()
};
let mut matched = Vec::new(); 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::<bool>(&entity).await? { if filter_fn.call_async::<bool>(&entity).await? {
matched.push(entity) matched.push(entity);
} }
} }
Ok(matched) Ok(matched)