@@ -686,7 +686,7 @@ mod test_flock {
686686
687687 /// Verify that `Flock::lock()` correctly obtains a lock, and subsequently unlocks upon drop.
688688 #[ test]
689- fn verify_lock_and_drop ( ) {
689+ fn lock_and_drop ( ) {
690690 // Get 2 `File` handles to same underlying file.
691691 let file1 = NamedTempFile :: new ( ) . unwrap ( ) ;
692692 let file2 = file1. reopen ( ) . unwrap ( ) ;
@@ -710,9 +710,32 @@ mod test_flock {
710710 }
711711 }
712712
713+ /// An exclusive lock can be downgraded
714+ #[ test]
715+ fn downgrade ( ) {
716+ let file1 = NamedTempFile :: new ( ) . unwrap ( ) ;
717+ let file2 = file1. reopen ( ) . unwrap ( ) ;
718+ let file1 = file1. into_file ( ) ;
719+
720+ // Lock first handle
721+ let lock1 = Flock :: lock ( file1, FlockArg :: LockExclusive ) . unwrap ( ) ;
722+
723+ // Attempt to lock second handle
724+ let file2 = Flock :: lock ( file2, FlockArg :: LockSharedNonblock )
725+ . unwrap_err ( )
726+ . 0 ;
727+
728+ // Downgrade the lock
729+ lock1. relock ( FlockArg :: LockShared ) . unwrap ( ) ;
730+
731+ // Attempt to lock second handle again (but successfully)
732+ Flock :: lock ( file2, FlockArg :: LockSharedNonblock )
733+ . expect ( "Expected locking to be successful." ) ;
734+ }
735+
713736 /// Verify that `Flock::unlock()` correctly obtains unlocks.
714737 #[ test]
715- fn verify_unlock ( ) {
738+ fn unlock ( ) {
716739 // Get 2 `File` handles to same underlying file.
717740 let file1 = NamedTempFile :: new ( ) . unwrap ( ) ;
718741 let file2 = file1. reopen ( ) . unwrap ( ) ;
@@ -729,4 +752,29 @@ mod test_flock {
729752 panic ! ( "Expected locking to be successful." ) ;
730753 }
731754 }
755+
756+ /// A shared lock can be upgraded
757+ #[ test]
758+ fn upgrade ( ) {
759+ let file1 = NamedTempFile :: new ( ) . unwrap ( ) ;
760+ let file2 = file1. reopen ( ) . unwrap ( ) ;
761+ let file3 = file1. reopen ( ) . unwrap ( ) ;
762+ let file1 = file1. into_file ( ) ;
763+
764+ // Lock first handle
765+ let lock1 = Flock :: lock ( file1, FlockArg :: LockShared ) . unwrap ( ) ;
766+
767+ // Attempt to lock second handle
768+ {
769+ Flock :: lock ( file2, FlockArg :: LockSharedNonblock )
770+ . expect ( "Locking should've succeeded" ) ;
771+ }
772+
773+ // Upgrade the lock
774+ lock1. relock ( FlockArg :: LockExclusive ) . unwrap ( ) ;
775+
776+ // Acquiring an additional shared lock should fail
777+ Flock :: lock ( file3, FlockArg :: LockSharedNonblock )
778+ . expect_err ( "Should not have been able to lock the file" ) ;
779+ }
732780}
0 commit comments