@@ -346,27 +346,63 @@ impl File {
346346 self . fsync ( )
347347 }
348348
349- pub fn lock ( & self ) -> io:: Result < ( ) > {
350- cvt ( unsafe {
351- let mut overlapped = mem:: zeroed ( ) ;
352- c:: LockFileEx (
349+ fn acquire_lock ( & self , flags : c:: LOCK_FILE_FLAGS ) -> io:: Result < ( ) > {
350+ unsafe {
351+ let mut overlapped: c:: OVERLAPPED = mem:: zeroed ( ) ;
352+ let event = c:: CreateEventW ( ptr:: null_mut ( ) , c:: FALSE , c:: FALSE , ptr:: null ( ) ) ;
353+ if event. is_null ( ) {
354+ return Err ( io:: Error :: last_os_error ( ) ) ;
355+ }
356+ overlapped. hEvent = event;
357+ let lock_result = cvt ( c:: LockFileEx (
353358 self . handle . as_raw_handle ( ) ,
354- c :: LOCKFILE_EXCLUSIVE_LOCK ,
359+ flags ,
355360 0 ,
356361 u32:: MAX ,
357362 u32:: MAX ,
358363 & mut overlapped,
359- )
360- } ) ?;
361- Ok ( ( ) )
364+ ) ) ;
365+
366+ let final_result = match lock_result {
367+ Ok ( _) => Ok ( ( ) ) ,
368+ Err ( err) => {
369+ if err. raw_os_error ( ) == Some ( c:: ERROR_IO_PENDING as i32 ) {
370+ // Wait for the lock to be acquired. This can happen asynchronously,
371+ // if the file handle was opened for async IO
372+ let wait_result = c:: WaitForSingleObject ( overlapped. hEvent , c:: INFINITE ) ;
373+ if wait_result == c:: WAIT_OBJECT_0 {
374+ // Wait completed successfully, get the lock operation status
375+ let mut bytes_transferred = 0 ;
376+ cvt ( c:: GetOverlappedResult (
377+ self . handle . as_raw_handle ( ) ,
378+ & mut overlapped,
379+ & mut bytes_transferred,
380+ c:: TRUE ,
381+ ) )
382+ . map ( |_| ( ) )
383+ } else if wait_result == c:: WAIT_FAILED {
384+ // Wait failed
385+ Err ( io:: Error :: last_os_error ( ) )
386+ } else {
387+ // WAIT_ABANDONED and WAIT_TIMEOUT should not be possible
388+ unreachable ! ( )
389+ }
390+ } else {
391+ Err ( err)
392+ }
393+ }
394+ } ;
395+ c:: CloseHandle ( overlapped. hEvent ) ;
396+ final_result
397+ }
398+ }
399+
400+ pub fn lock ( & self ) -> io:: Result < ( ) > {
401+ self . acquire_lock ( c:: LOCKFILE_EXCLUSIVE_LOCK )
362402 }
363403
364404 pub fn lock_shared ( & self ) -> io:: Result < ( ) > {
365- cvt ( unsafe {
366- let mut overlapped = mem:: zeroed ( ) ;
367- c:: LockFileEx ( self . handle . as_raw_handle ( ) , 0 , 0 , u32:: MAX , u32:: MAX , & mut overlapped)
368- } ) ?;
369- Ok ( ( ) )
405+ self . acquire_lock ( 0 )
370406 }
371407
372408 pub fn try_lock ( & self ) -> io:: Result < bool > {
0 commit comments