@@ -813,25 +813,58 @@ mod private {
813813 }
814814
815815 pub async fn read ( & self ) -> Result < RoomEventCacheStateLockReadGuard < ' _ > , EventCacheError > {
816- let state_guard = self . locked_state . read ( ) . await ;
817- let store_guard = match state_guard. store . lock ( ) . await ? {
818- EventCacheStoreLockState :: Clean ( guard) => guard,
819- EventCacheStoreLockState :: Dirty ( _guard) => todo ! ( "Dirty lock" ) ,
820- } ;
816+ // Take a write-lock in case the lock is dirty and we need to reset the state.
817+ let state_guard = self . locked_state . write ( ) . await ;
821818
822- Ok ( RoomEventCacheStateLockReadGuard { state : state_guard, store : store_guard } )
819+ match state_guard. store . lock ( ) . await ? {
820+ EventCacheStoreLockState :: Clean ( store_guard) => {
821+ Ok ( RoomEventCacheStateLockReadGuard {
822+ // Downgrade to a read-lock.
823+ state : state_guard. downgrade ( ) ,
824+ store : store_guard,
825+ } )
826+ }
827+ EventCacheStoreLockState :: Dirty ( store_guard) => {
828+ let mut guard = RoomEventCacheStateLockWriteGuard {
829+ state : state_guard,
830+ store : store_guard,
831+ } ;
832+ guard. shrink_to_last_chunk ( ) . await ?;
833+
834+ // All good now, mark the cross-process lock as non-dirty.
835+ EventCacheStoreLockGuard :: clear_dirty ( & guard. store ) ;
836+
837+ Ok ( RoomEventCacheStateLockReadGuard {
838+ // Downgrade to a read-lock.
839+ state : guard. state . downgrade ( ) ,
840+ store : guard. store ,
841+ } )
842+ }
843+ }
823844 }
824845
825846 pub async fn write (
826847 & self ,
827848 ) -> Result < RoomEventCacheStateLockWriteGuard < ' _ > , EventCacheError > {
828849 let state_guard = self . locked_state . write ( ) . await ;
829- let store_guard = match state_guard. store . lock ( ) . await ? {
830- EventCacheStoreLockState :: Clean ( guard) => guard,
831- EventCacheStoreLockState :: Dirty ( _guard) => todo ! ( "Dirty lock" ) ,
832- } ;
833850
834- Ok ( RoomEventCacheStateLockWriteGuard { state : state_guard, store : store_guard } )
851+ match state_guard. store . lock ( ) . await ? {
852+ EventCacheStoreLockState :: Clean ( store_guard) => {
853+ Ok ( RoomEventCacheStateLockWriteGuard { state : state_guard, store : store_guard } )
854+ }
855+ EventCacheStoreLockState :: Dirty ( store_guard) => {
856+ let mut guard = RoomEventCacheStateLockWriteGuard {
857+ state : state_guard,
858+ store : store_guard,
859+ } ;
860+ guard. shrink_to_last_chunk ( ) . await ?;
861+
862+ // All good now, mark the cross-process lock as non-dirty.
863+ EventCacheStoreLockGuard :: clear_dirty ( & guard. store ) ;
864+
865+ Ok ( guard)
866+ }
867+ }
835868 }
836869 }
837870
0 commit comments