diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 61e74a2c9..bc7beacc2 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -165,7 +165,7 @@ pub(crate) struct ClientInner { pub(crate) key_claim_lock: Mutex<()>, /// Lock to ensure that only one members request is running at a time, per /// room. - pub(crate) members_request_locks: Mutex>>>, + pub(crate) members_request_locks: Mutex>>>>, /// Locks for requests on the encryption state of rooms. pub(crate) encryption_state_request_locks: Mutex>>>, pub(crate) typing_notice_times: DashMap, diff --git a/crates/matrix-sdk/src/error.rs b/crates/matrix-sdk/src/error.rs index ed457ec3f..d2a87392f 100644 --- a/crates/matrix-sdk/src/error.rs +++ b/crates/matrix-sdk/src/error.rs @@ -266,6 +266,10 @@ pub enum Error { #[error(transparent)] Oidc(#[from] crate::oidc::OidcError), + /// A concurrent request to a deduplicated request has failed. + #[error("a concurrent request failed; see logs for details")] + ConcurrentRequestFailed, + /// An other error was raised /// this might happen because encryption was enabled on the base-crate /// but not here and that raised. diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 1a3e63eb0..564d9719f 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -388,14 +388,12 @@ impl Room { // If a member request is already going on, await the release of // the lock. drop(map); - _ = mutex.lock().await; - - Ok(None) + return mutex.lock().await.map(|()| None).map_err(|()| Error::ConcurrentRequestFailed); } else { - let mutex = Arc::new(Mutex::new(())); - map.insert(self.inner.room_id().to_owned(), mutex.clone()); + let request_mutex = Arc::new(Mutex::new(Ok(()))); + map.insert(self.inner.room_id().to_owned(), request_mutex.clone()); - let _guard = mutex.lock().await; + let mut request_guard = request_mutex.lock().await; drop(map); let request = get_member_events::v3::Request::new(self.inner.room_id().to_owned()); @@ -420,6 +418,9 @@ impl Room { } Err(err) => { + // Mark the request as failed. + *request_guard = Err(()); + // Remove the request from the in-flights set. self.client .inner