@@ -4332,6 +4332,87 @@ mod timed_tests {
43324332 }
43334333 }
43344334
4335+ #[ async_test]
4336+ async fn test_load_when_dirty ( ) {
4337+ let room_id_0 = room_id ! ( "!raclette:patate.ch" ) ;
4338+ let room_id_1 = room_id ! ( "!morbiflette:patate.ch" ) ;
4339+
4340+ // The storage shared by the two clients.
4341+ let event_cache_store = MemoryStore :: new ( ) ;
4342+
4343+ // Client for the process 0.
4344+ let client_p0 = MockClientBuilder :: new ( None )
4345+ . on_builder ( |builder| {
4346+ builder. store_config (
4347+ StoreConfig :: new ( "process #0" . to_owned ( ) )
4348+ . event_cache_store ( event_cache_store. clone ( ) ) ,
4349+ )
4350+ } )
4351+ . build ( )
4352+ . await ;
4353+
4354+ // Client for the process 1.
4355+ let client_p1 = MockClientBuilder :: new ( None )
4356+ . on_builder ( |builder| {
4357+ builder. store_config (
4358+ StoreConfig :: new ( "process #1" . to_owned ( ) ) . event_cache_store ( event_cache_store) ,
4359+ )
4360+ } )
4361+ . build ( )
4362+ . await ;
4363+
4364+ // Subscribe the event caches, and create the room.
4365+ let ( room_event_cache_0_p0, room_event_cache_0_p1) = {
4366+ let event_cache_p0 = client_p0. event_cache ( ) ;
4367+ event_cache_p0. subscribe ( ) . unwrap ( ) ;
4368+
4369+ let event_cache_p1 = client_p1. event_cache ( ) ;
4370+ event_cache_p1. subscribe ( ) . unwrap ( ) ;
4371+
4372+ client_p0
4373+ . base_client ( )
4374+ . get_or_create_room ( room_id_0, matrix_sdk_base:: RoomState :: Joined ) ;
4375+ client_p0
4376+ . base_client ( )
4377+ . get_or_create_room ( room_id_1, matrix_sdk_base:: RoomState :: Joined ) ;
4378+
4379+ client_p1
4380+ . base_client ( )
4381+ . get_or_create_room ( room_id_0, matrix_sdk_base:: RoomState :: Joined ) ;
4382+ client_p1
4383+ . base_client ( )
4384+ . get_or_create_room ( room_id_1, matrix_sdk_base:: RoomState :: Joined ) ;
4385+
4386+ let ( room_event_cache_0_p0, _drop_handles) =
4387+ client_p0. get_room ( room_id_0) . unwrap ( ) . event_cache ( ) . await . unwrap ( ) ;
4388+ let ( room_event_cache_0_p1, _drop_handles) =
4389+ client_p1. get_room ( room_id_0) . unwrap ( ) . event_cache ( ) . await . unwrap ( ) ;
4390+
4391+ ( room_event_cache_0_p0, room_event_cache_0_p1)
4392+ } ;
4393+
4394+ // Let's make the cross-process lock over the store dirty.
4395+ {
4396+ drop ( room_event_cache_0_p0. inner . state . read ( ) . await . unwrap ( ) ) ;
4397+ drop ( room_event_cache_0_p1. inner . state . read ( ) . await . unwrap ( ) ) ;
4398+ }
4399+
4400+ // Create the `RoomEventCache` for `room_id_1`. During its creation, the
4401+ // cross-process lock over the store MUST be dirty, which makes no difference as
4402+ // a clean one: the state is just loaded, not reloaded.
4403+ let ( room_event_cache_1_p0, _) =
4404+ client_p0. get_room ( room_id_1) . unwrap ( ) . event_cache ( ) . await . unwrap ( ) ;
4405+
4406+ // Check the lock isn't dirty because it's been cleared.
4407+ {
4408+ let guard = room_event_cache_1_p0. inner . state . read ( ) . await . unwrap ( ) ;
4409+ assert ! ( guard. is_dirty( ) . not( ) ) ;
4410+ }
4411+
4412+ // The only way to test this behaviour is to see that the dirty block in
4413+ // `RoomEventCacheStateLock` is covered by this test.
4414+ }
4415+
43354416 async fn event_loaded ( room_event_cache : & RoomEventCache , event_id : & EventId ) -> bool {
43364417 room_event_cache
43374418 . rfind_map_event_in_memory_by ( |event| {
0 commit comments