Skip to content

Commit 34b9b1e

Browse files
committed
Implement fallback for File::try_lock
- `try_lock` can just use `LockFile` instead of `LockFileEx` (= 9x/ME support) - `try_lock_shared` will just fail on 9x/ME as shared locks are not supported - blocking lock is not supported on 9x/ME either. We try `try_lock` in hopes of getting the lock instead, and then fall back to the proper lock impl, which will fail on 9x/ME
1 parent 83ad711 commit 34b9b1e

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

library/std/src/sys/pal/windows/c.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,3 +703,21 @@ compat_fn_with_fallback! {
703703
rtabort!("unimplemented")
704704
}
705705
}
706+
707+
#[cfg(target_vendor = "rust9x")]
708+
compat_fn_with_fallback! {
709+
pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
710+
// >= NT
711+
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex
712+
pub fn LockFileEx(
713+
hfile: HANDLE,
714+
dwflags: LOCK_FILE_FLAGS,
715+
dwreserved: u32,
716+
nnumberofbytestolocklow: u32,
717+
nnumberofbytestolockhigh: u32,
718+
lpoverlapped: *mut OVERLAPPED
719+
) -> BOOL {
720+
unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
721+
FALSE
722+
}
723+
}

library/std/src/sys/pal/windows/c/bindings.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2366,6 +2366,7 @@ Windows.Win32.Storage.FileSystem.GetFullPathNameW
23662366
Windows.Win32.Storage.FileSystem.GetTempPathW
23672367
Windows.Win32.Storage.FileSystem.INVALID_FILE_ATTRIBUTES
23682368
Windows.Win32.Storage.FileSystem.INVALID_SET_FILE_POINTER
2369+
Windows.Win32.Storage.FileSystem.LockFile
23692370
Windows.Win32.Storage.FileSystem.LOCKFILE_EXCLUSIVE_LOCK
23702371
Windows.Win32.Storage.FileSystem.LOCKFILE_FAIL_IMMEDIATELY
23712372
Windows.Win32.Storage.FileSystem.LockFileEx

library/std/src/sys/pal/windows/c/windows_sys.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ windows_targets::link!("kernel32.dll" "system" fn InitializeProcThreadAttributeL
8080
windows_targets::link!("kernel32.dll" "system" fn LeaveCriticalSection(lpcriticalsection : *mut CRITICAL_SECTION));
8181
windows_targets::link!("kernel32.dll" "system" fn LoadLibraryA(lplibfilename : PCSTR) -> HMODULE);
8282
windows_targets::link!("kernel32.dll" "system" fn LocalFree(hmem : HLOCAL) -> HLOCAL);
83+
windows_targets::link!("kernel32.dll" "system" fn LockFile(hfile : HANDLE, dwfileoffsetlow : u32, dwfileoffsethigh : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32) -> BOOL);
8384
windows_targets::link!("kernel32.dll" "system" fn LockFileEx(hfile : HANDLE, dwflags : LOCK_FILE_FLAGS, dwreserved : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
8485
windows_targets::link!("kernel32.dll" "system" fn MoveFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, dwflags : MOVE_FILE_FLAGS) -> BOOL);
8586
windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage : u32, dwflags : MULTI_BYTE_TO_WIDE_CHAR_FLAGS, lpmultibytestr : PCSTR, cbmultibyte : i32, lpwidecharstr : PWSTR, cchwidechar : i32) -> i32);

library/std/src/sys/pal/windows/fs.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,15 @@ impl File {
459459
}
460460

461461
pub fn lock(&self) -> io::Result<()> {
462+
#[cfg(target_vendor = "rust9x")]
463+
{
464+
// try `LockFile`/`try_lock`, as that one is available on 9x/ME
465+
if self.try_lock()? {
466+
return Ok(());
467+
}
468+
469+
// otherwise just fail the call to `LockFileEx` here
470+
}
462471
self.acquire_lock(c::LOCKFILE_EXCLUSIVE_LOCK)
463472
}
464473

@@ -467,17 +476,8 @@ impl File {
467476
}
468477

469478
pub fn try_lock(&self) -> io::Result<bool> {
470-
let result = cvt(unsafe {
471-
let mut overlapped = mem::zeroed();
472-
c::LockFileEx(
473-
self.handle.as_raw_handle(),
474-
c::LOCKFILE_EXCLUSIVE_LOCK | c::LOCKFILE_FAIL_IMMEDIATELY,
475-
0,
476-
u32::MAX,
477-
u32::MAX,
478-
&mut overlapped,
479-
)
480-
});
479+
let result =
480+
cvt(unsafe { c::LockFile(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX) });
481481

482482
match result {
483483
Ok(_) => Ok(true),

0 commit comments

Comments
 (0)