From 98fed1d2ebbb90610fb83806d88f11b532dbc73d Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 27 Jun 2023 16:29:35 +0200 Subject: [PATCH] chore: use smaller critical sections This opens up a possible race condition where an embedder calls the method twice, generating two new rooms, but then it's fine as long as they don't cache them somewhere, which we expect they don't. --- crates/matrix-sdk-ui/src/room_list/mod.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk-ui/src/room_list/mod.rs b/crates/matrix-sdk-ui/src/room_list/mod.rs index 38e6193d3..8fe36d50a 100644 --- a/crates/matrix-sdk-ui/src/room_list/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list/mod.rs @@ -87,14 +87,14 @@ use ruma::{ }; pub use state::*; use thiserror::Error; -use tokio::sync::Mutex; +use tokio::sync::RwLock; /// The [`RoomListService`] type. See the module's documentation to learn more. #[derive(Debug)] pub struct RoomListService { sliding_sync: Arc, /// Room cache, to avoid recreating `Room`s everytime users fetch them. - rooms: Arc>>, + rooms: Arc>>, state: Observable, } @@ -285,16 +285,20 @@ impl RoomListService { /// Get a [`Room`] if it exists. pub async fn room(&self, room_id: &RoomId) -> Result { - let mut rooms = self.rooms.lock().await; - if let Some(room) = rooms.get(room_id) { - return Ok(room.clone()); + { + let rooms = self.rooms.read().await; + if let Some(room) = rooms.get(room_id) { + return Ok(room.clone()); + } } + let room = match self.sliding_sync.get_room(room_id).await { - Some(room) => Room::new(self.sliding_sync.clone(), room), - None => Err(Error::RoomNotFound(room_id.to_owned())), + Some(room) => Room::new(self.sliding_sync.clone(), room)?, + None => return Err(Error::RoomNotFound(room_id.to_owned())), }; - let room = room?; - rooms.insert(room_id.to_owned(), room.clone()); + + self.rooms.write().await.insert(room_id.to_owned(), room.clone()); + Ok(room) }