From f6a100bec7983fc12dbda5ce6dfd2c5fbc52f3e5 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 4 Jun 2024 11:04:48 +0200 Subject: [PATCH] pagination: don't hold onto the waited_for_initial_prev_token lock for too long While this mutex is taken, in `oldest_token()` we can get a hold of the RoomEvent mutex, making it so that the `waited_...` token covers the critical region of room events. Unfortunately, in `clear()`, we're taking these two locks in the opposite order, implying that the room events critical region now overlaps that of the `waited_...` lock. The way to break the cycle is to keep the `waited_` token for as short as possible. --- crates/matrix-sdk/src/event_cache/pagination.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/matrix-sdk/src/event_cache/pagination.rs b/crates/matrix-sdk/src/event_cache/pagination.rs index def8063c7d7..e2b3aae4cdf 100644 --- a/crates/matrix-sdk/src/event_cache/pagination.rs +++ b/crates/matrix-sdk/src/event_cache/pagination.rs @@ -248,18 +248,18 @@ impl RoomPagination { Ok(Some(BackPaginationOutcome { events, reached_start })) } - /// Test-only function to get the latest pagination token, as stored in the - /// room events linked list. + /// Get the latest pagination token, as stored in the room events linked + /// list. #[doc(hidden)] pub async fn get_or_wait_for_token(&self) -> Option { const DEFAULT_INITIAL_WAIT_DURATION: Duration = Duration::from_secs(3); - let mut waited = self.inner.pagination.waited_for_initial_prev_token.lock().await; - if *waited { + let waited = *self.inner.pagination.waited_for_initial_prev_token.lock().await; + if waited { self.oldest_token(None).await } else { let token = self.oldest_token(Some(DEFAULT_INITIAL_WAIT_DURATION)).await; - *waited = true; + *self.inner.pagination.waited_for_initial_prev_token.lock().await = true; token } }