From 317d9ffdca6e48cd81ea164af30436ebbd5ce4f8 Mon Sep 17 00:00:00 2001 From: spr-equinox <66425054+spr-equinox@users.noreply.github.com> Date: Sun, 15 Jun 2025 21:37:31 +0800 Subject: [PATCH] Fix deadlock when throwing items (#865) (#902) * Fix deadlock when throwing items try test again * remove unnecessary async --- pumpkin-inventory/src/screen_handler.rs | 6 +++--- pumpkin/src/entity/player.rs | 15 ++++++--------- pumpkin/src/net/packet/play.rs | 4 +--- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/pumpkin-inventory/src/screen_handler.rs b/pumpkin-inventory/src/screen_handler.rs index 814f36a32..d7303f288 100644 --- a/pumpkin-inventory/src/screen_handler.rs +++ b/pumpkin-inventory/src/screen_handler.rs @@ -165,7 +165,7 @@ pub trait ScreenHandler: Send + Sync { } } - async fn set_received_hash(&mut self, slot: usize, hash: OptionalItemStackHash) { + fn set_received_hash(&mut self, slot: usize, hash: OptionalItemStackHash) { let behaviour = self.get_behaviour_mut(); if slot < behaviour.previous_tracked_stacks.len() { behaviour.previous_tracked_stacks[slot].set_received_hash(hash); @@ -178,12 +178,12 @@ pub trait ScreenHandler: Send + Sync { } } - async fn set_received_stack(&mut self, slot: usize, stack: ItemStack) { + fn set_received_stack(&mut self, slot: usize, stack: ItemStack) { let behaviour = self.get_behaviour_mut(); behaviour.previous_tracked_stacks[slot].set_received_stack(stack); } - async fn set_received_cursor_hash(&mut self, hash: OptionalItemStackHash) { + fn set_received_cursor_hash(&mut self, hash: OptionalItemStackHash) { let behaviour = self.get_behaviour_mut(); behaviour.previous_cursor_stack.set_received_hash(hash); } diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index c4c637efd..2f4203a76 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -1454,6 +1454,8 @@ impl Player { } pub async fn drop_held_item(&self, drop_stack: bool) { + // should be locked first otherwise cause deadlock in tick() (this thread lock stack, that thread lock screen_handler) + let screen_binding = self.current_screen_handler.lock().await; let binding = self.inventory.held_item(); let mut item_stack = binding.lock().await; @@ -1464,16 +1466,13 @@ impl Player { item_stack.decrement(drop_amount); let selected_slot = self.inventory.get_selected_slot(); let inv: Arc = self.inventory.clone(); - let binding = self.current_screen_handler.lock().await; - let mut screen_handler = binding.lock().await; + let mut screen_handler = screen_binding.lock().await; let slot_index = screen_handler .get_slot_index(&inv, selected_slot as usize) .await; if let Some(slot_index) = slot_index { - screen_handler - .set_received_stack(slot_index, *item_stack) - .await; + screen_handler.set_received_stack(slot_index, *item_stack); } } } @@ -1821,12 +1820,10 @@ impl Player { .await; for (key, value) in packet.array_of_changed_slots { - screen_handler.set_received_hash(key as usize, value).await; + screen_handler.set_received_hash(key as usize, value); } - screen_handler - .set_received_cursor_hash(packet.carried_item) - .await; + screen_handler.set_received_cursor_hash(packet.carried_item); screen_handler.enable_sync().await; if not_in_sync { diff --git a/pumpkin/src/net/packet/play.rs b/pumpkin/src/net/packet/play.rs index feafbda2a..5afa90668 100644 --- a/pumpkin/src/net/packet/play.rs +++ b/pumpkin/src/net/packet/play.rs @@ -1459,9 +1459,7 @@ impl Player { .await .set_stack(item_stack) .await; - player_screen_handler - .set_received_stack(packet.slot as usize, item_stack) - .await; + player_screen_handler.set_received_stack(packet.slot as usize, item_stack); player_screen_handler.send_content_updates().await; } else if is_negative && is_legal { // Item drop