@@ -56,6 +56,15 @@ impl SpinRwLock {
5656 Self :: INIT
5757 }
5858
59+ /// Reset the lock to the unlocked state.
60+ ///
61+ /// # Safety
62+ /// The caller must ensure no other thread is currently accessing this lock
63+ /// (holding guards or attempting to acquire).
64+ pub unsafe fn reset ( & self ) {
65+ self . state . store ( 0 , Ordering :: Release ) ;
66+ }
67+
5968 pub fn read ( & self ) -> ReadGuard < ' _ > {
6069 self . _read ( ) ;
6170 ReadGuard { lock : self }
@@ -855,4 +864,34 @@ mod tests {
855864 assert ! ( data. try_read( ) . is_none( ) ) ;
856865 drop ( wg) ;
857866 }
867+
868+ // --- reset ---
869+
870+ #[ test]
871+ fn reset_unlocks_after_write ( ) {
872+ let lock = SpinRwLock :: new ( ) ;
873+ let _wg = lock. write ( ) ;
874+ // Simulate a crash: forget the guard so unlock_write never runs.
875+ core:: mem:: forget ( _wg) ;
876+ // Lock is now stuck in writer-held state.
877+ assert ! ( lock. try_write( ) . is_none( ) ) ;
878+ assert ! ( lock. try_read( ) . is_none( ) ) ;
879+ // SAFETY: no other threads are accessing this lock.
880+ unsafe { lock. reset ( ) } ;
881+ // Lock is usable again.
882+ assert ! ( lock. try_read( ) . is_some( ) ) ;
883+ assert ! ( lock. try_write( ) . is_some( ) ) ;
884+ }
885+
886+ #[ test]
887+ fn reset_unlocks_after_read ( ) {
888+ let lock = SpinRwLock :: new ( ) ;
889+ let _rg = lock. read ( ) ;
890+ core:: mem:: forget ( _rg) ;
891+ // Lock is stuck with a reader.
892+ assert ! ( lock. try_write( ) . is_none( ) ) ;
893+ // SAFETY: no other threads are accessing this lock.
894+ unsafe { lock. reset ( ) } ;
895+ assert ! ( lock. try_write( ) . is_some( ) ) ;
896+ }
858897}
0 commit comments