Fix deadlocking (hopefully)

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 3 years ago
parent fe0180e54c
commit 74c707855d
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

60
Cargo.lock generated

@ -140,13 +140,14 @@ dependencies = [
[[package]] [[package]]
name = "dashmap" name = "dashmap"
version = "5.2.0" version = "5.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c" checksum = "3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"num_cpus", "hashbrown 0.12.1",
"parking_lot", "lock_api",
"parking_lot_core",
"serde", "serde",
] ]
@ -357,13 +358,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]] [[package]]
name = "hermit-abi" name = "hashbrown"
version = "0.1.19" version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "http" name = "http"
@ -467,7 +465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown", "hashbrown 0.11.2",
] ]
[[package]] [[package]]
@ -628,16 +626,6 @@ dependencies = [
"autocfg", "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]] [[package]]
name = "num_threads" name = "num_threads"
version = "0.1.5" version = "0.1.5"
@ -707,9 +695,9 @@ dependencies = [
[[package]] [[package]]
name = "parking_lot_core" name = "parking_lot_core"
version = "0.9.2" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -1033,7 +1021,7 @@ dependencies = [
[[package]] [[package]]
name = "serenity-additions" name = "serenity-additions"
version = "0.3.1" version = "0.3.2"
dependencies = [ dependencies = [
"dashmap", "dashmap",
"futures", "futures",
@ -1518,9 +1506,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.34.0" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [ dependencies = [
"windows_aarch64_msvc", "windows_aarch64_msvc",
"windows_i686_gnu", "windows_i686_gnu",
@ -1531,33 +1519,33 @@ dependencies = [
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.34.0" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.34.0" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.34.0" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.34.0" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.34.0" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]] [[package]]
name = "winreg" name = "winreg"

@ -1,6 +1,6 @@
[package] [package]
name = "serenity-additions" name = "serenity-additions"
version = "0.3.1" version = "0.3.2"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
description = "Menus and self deleting messages for the serenity discord framework" description = "Menus and self deleting messages for the serenity discord framework"
@ -21,7 +21,7 @@ thiserror = "1.0.30"
tracing= "0.1.33" tracing= "0.1.33"
futures = "0.3.21" futures = "0.3.21"
serde_json = "1.0.79" serde_json = "1.0.79"
dashmap = "5.2.0" dashmap = "5.3.4"
[dependencies.serenity] [dependencies.serenity]
version = "0.11.1" version = "0.11.1"

@ -23,13 +23,16 @@ pub async fn start_update_loop(ctx: &Context) -> Result<()> {
tracing::trace!("Updating messages..."); tracing::trace!("Updating messages...");
let mut frozen_messages = Vec::new(); let mut frozen_messages = Vec::new();
for entry in event_messages.iter() { for (key, value) in event_messages
let mut msg = entry.value().lock().await; .iter()
.map(|e| (e.key().clone(), e.value().clone()))
{
let mut msg = value.lock().await;
if let Err(e) = msg.update(&http).await { if let Err(e) = msg.update(&http).await {
tracing::error!("Failed to update message: {:?}", e); tracing::error!("Failed to update message: {:?}", e);
} }
if msg.is_frozen() { if msg.is_frozen() {
frozen_messages.push(*entry.key()); frozen_messages.push(key);
} }
} }
for key in frozen_messages { for key in frozen_messages {

@ -110,10 +110,7 @@ impl<'a> Menu<'a> {
/// Recreates the message completely /// Recreates the message completely
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
pub async fn recreate(&self, http: &Http) -> Result<()> { pub async fn recreate(&self, http: &Http) -> Result<()> {
let old_handle = { let old_handle = self.get_handle().await;
let handle = self.message.read().await;
(*handle).clone()
};
let current_page = self.get_current_page()?.get().await?; let current_page = self.get_current_page()?.get().await?;
let message = http let message = http
@ -140,6 +137,7 @@ impl<'a> Menu<'a> {
{ {
tracing::debug!("Changing key of message"); tracing::debug!("Changing key of message");
let menu = self.listeners.remove(&old_handle).unwrap(); let menu = self.listeners.remove(&old_handle).unwrap();
tracing::debug!("Inserting new key");
self.listeners.insert(new_handle, menu.1); self.listeners.insert(new_handle, menu.1);
} }
tracing::debug!("Deleting original message"); tracing::debug!("Deleting original message");
@ -148,6 +146,13 @@ impl<'a> Menu<'a> {
Ok(()) 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] #[async_trait]
@ -166,10 +171,7 @@ impl<'a> EventDrivenMessage for Menu<'a> {
} else if self.sticky { } else if self.sticky {
tracing::debug!("Message is sticky. Checking for new messages in channel..."); tracing::debug!("Message is sticky. Checking for new messages in channel...");
let handle = { let handle = self.get_handle().await;
let handle = self.message.read().await;
(*handle).clone()
};
let channel_id = ChannelId(handle.channel_id); let channel_id = ChannelId(handle.channel_id);
let messages = channel_id let messages = channel_id
.messages(http, |p| p.after(handle.message_id).limit(1)) .messages(http, |p| p.after(handle.message_id).limit(1))

Loading…
Cancel
Save