Skip to content

Commit

Permalink
Implement fallback for File::try_lock
Browse files Browse the repository at this point in the history
- `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
  • Loading branch information
seritools committed Dec 25, 2024
1 parent 5beba8d commit 8e99671
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 11 deletions.
18 changes: 18 additions & 0 deletions library/std/src/sys/pal/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,3 +686,21 @@ compat_fn_with_fallback! {
rtabort!("unimplemented")
}
}

#[cfg(target_vendor = "rust9x")]
compat_fn_with_fallback! {
pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
// >= NT
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex
pub fn LockFileEx(
hfile: HANDLE,
dwflags: LOCK_FILE_FLAGS,
dwreserved: u32,
nnumberofbytestolocklow: u32,
nnumberofbytestolockhigh: u32,
lpoverlapped: *mut OVERLAPPED
) -> BOOL {
unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
FALSE
}
}
1 change: 1 addition & 0 deletions library/std/src/sys/pal/windows/c/bindings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2365,6 +2365,7 @@ Windows.Win32.Storage.FileSystem.GetFullPathNameW
Windows.Win32.Storage.FileSystem.GetTempPathW
Windows.Win32.Storage.FileSystem.INVALID_FILE_ATTRIBUTES
Windows.Win32.Storage.FileSystem.INVALID_SET_FILE_POINTER
Windows.Win32.Storage.FileSystem.LockFile
Windows.Win32.Storage.FileSystem.LOCKFILE_EXCLUSIVE_LOCK
Windows.Win32.Storage.FileSystem.LOCKFILE_FAIL_IMMEDIATELY
Windows.Win32.Storage.FileSystem.LockFileEx
Expand Down
1 change: 1 addition & 0 deletions library/std/src/sys/pal/windows/c/windows_sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ windows_targets::link!("kernel32.dll" "system" fn InitializeProcThreadAttributeL
windows_targets::link!("kernel32.dll" "system" fn LeaveCriticalSection(lpcriticalsection : *mut CRITICAL_SECTION));
windows_targets::link!("kernel32.dll" "system" fn LoadLibraryA(lplibfilename : PCSTR) -> HMODULE);
windows_targets::link!("kernel32.dll" "system" fn LocalFree(hmem : HLOCAL) -> HLOCAL);
windows_targets::link!("kernel32.dll" "system" fn LockFile(hfile : HANDLE, dwfileoffsetlow : u32, dwfileoffsethigh : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32) -> BOOL);
windows_targets::link!("kernel32.dll" "system" fn LockFileEx(hfile : HANDLE, dwflags : LOCK_FILE_FLAGS, dwreserved : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
windows_targets::link!("kernel32.dll" "system" fn MoveFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, dwflags : MOVE_FILE_FLAGS) -> BOOL);
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);
Expand Down
22 changes: 11 additions & 11 deletions library/std/src/sys/pal/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,15 @@ impl File {
}

pub fn lock(&self) -> io::Result<()> {
#[cfg(target_vendor = "rust9x")]
{
// try `LockFile`/`try_lock`, as that one is available on 9x/ME
if self.try_lock()? {
return Ok(());
}

// otherwise just fail the call to `LockFileEx` here
}
self.acquire_lock(c::LOCKFILE_EXCLUSIVE_LOCK)
}

Expand All @@ -451,17 +460,8 @@ impl File {
}

pub fn try_lock(&self) -> io::Result<bool> {
let result = cvt(unsafe {
let mut overlapped = mem::zeroed();
c::LockFileEx(
self.handle.as_raw_handle(),
c::LOCKFILE_EXCLUSIVE_LOCK | c::LOCKFILE_FAIL_IMMEDIATELY,
0,
u32::MAX,
u32::MAX,
&mut overlapped,
)
});
let result =
cvt(unsafe { c::LockFile(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX) });

match result {
Ok(_) => Ok(true),
Expand Down

0 comments on commit 8e99671

Please sign in to comment.