From 74c707855d23e258cf54ff5e5fe86c7d83d79c20 Mon Sep 17 00:00:00 2001 From: trivernis Date: Tue, 7 Jun 2022 17:45:05 +0200 Subject: [PATCH] Fix deadlocking (hopefully) Signed-off-by: trivernis --- Cargo.lock | 60 ++++++++++++++--------------------- Cargo.toml | 4 +-- src/events/event_callbacks.rs | 9 ++++-- src/menu/menu.rs | 18 ++++++----- 4 files changed, 42 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e44054..dfac35b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -140,13 +140,14 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.2.0" +version = "5.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c" +checksum = "3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f" dependencies = [ "cfg-if", - "num_cpus", - "parking_lot", + "hashbrown 0.12.1", + "lock_api", + "parking_lot_core", "serde", ] @@ -357,13 +358,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" [[package]] name = "http" @@ -467,7 +465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.11.2", ] [[package]] @@ -628,16 +626,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_threads" version = "0.1.5" @@ -707,9 +695,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if", "libc", @@ -1033,7 +1021,7 @@ dependencies = [ [[package]] name = "serenity-additions" -version = "0.3.1" +version = "0.3.2" dependencies = [ "dashmap", "futures", @@ -1518,9 +1506,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ "windows_aarch64_msvc", "windows_i686_gnu", @@ -1531,33 +1519,33 @@ dependencies = [ [[package]] name = "windows_aarch64_msvc" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_i686_gnu" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_msvc" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_x86_64_gnu" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_msvc" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "winreg" diff --git a/Cargo.toml b/Cargo.toml index 9404313..ab567ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serenity-additions" -version = "0.3.1" +version = "0.3.2" authors = ["trivernis "] edition = "2018" description = "Menus and self deleting messages for the serenity discord framework" @@ -21,7 +21,7 @@ thiserror = "1.0.30" tracing= "0.1.33" futures = "0.3.21" serde_json = "1.0.79" -dashmap = "5.2.0" +dashmap = "5.3.4" [dependencies.serenity] version = "0.11.1" diff --git a/src/events/event_callbacks.rs b/src/events/event_callbacks.rs index db29777..a17727d 100644 --- a/src/events/event_callbacks.rs +++ b/src/events/event_callbacks.rs @@ -23,13 +23,16 @@ pub async fn start_update_loop(ctx: &Context) -> Result<()> { tracing::trace!("Updating messages..."); let mut frozen_messages = Vec::new(); - for entry in event_messages.iter() { - let mut msg = entry.value().lock().await; + for (key, value) in event_messages + .iter() + .map(|e| (e.key().clone(), e.value().clone())) + { + let mut msg = value.lock().await; if let Err(e) = msg.update(&http).await { tracing::error!("Failed to update message: {:?}", e); } if msg.is_frozen() { - frozen_messages.push(*entry.key()); + frozen_messages.push(key); } } for key in frozen_messages { diff --git a/src/menu/menu.rs b/src/menu/menu.rs index ca76c01..b2a8731 100644 --- a/src/menu/menu.rs +++ b/src/menu/menu.rs @@ -110,10 +110,7 @@ impl<'a> Menu<'a> { /// Recreates the message completely #[tracing::instrument(level = "debug", skip_all)] pub async fn recreate(&self, http: &Http) -> Result<()> { - let old_handle = { - let handle = self.message.read().await; - (*handle).clone() - }; + let old_handle = self.get_handle().await; let current_page = self.get_current_page()?.get().await?; let message = http @@ -140,6 +137,7 @@ impl<'a> Menu<'a> { { tracing::debug!("Changing key of message"); let menu = self.listeners.remove(&old_handle).unwrap(); + tracing::debug!("Inserting new key"); self.listeners.insert(new_handle, menu.1); } tracing::debug!("Deleting original message"); @@ -148,6 +146,13 @@ impl<'a> Menu<'a> { Ok(()) } + + /// Returns the handle of the menus message + /// Locking behaviour: May deadlock when already holding a lock to [Self::messages] + async fn get_handle(&self) -> MessageHandle { + let handle = self.message.read().await; + (*handle).clone() + } } #[async_trait] @@ -166,10 +171,7 @@ impl<'a> EventDrivenMessage for Menu<'a> { } else if self.sticky { tracing::debug!("Message is sticky. Checking for new messages in channel..."); - let handle = { - let handle = self.message.read().await; - (*handle).clone() - }; + let handle = self.get_handle().await; let channel_id = ChannelId(handle.channel_id); let messages = channel_id .messages(http, |p| p.after(handle.message_id).limit(1))