authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-06-28 12:06:14-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-06-29 14:25:04-07:00
log488f68069ba0a81f46a5afe721b908cfd3c61f76
tree4f2316eefbe164a0b42864dbb0d2a3c128ed7417
parent3d7ae63c6f0b01456a411b31bad2322166634868

implement std.fs.File.setLock for Windows


3 files changed, 106 insertions(+), 2 deletions(-)

lib/std/fs/file.zig+29-2
...@@ -840,10 +840,37 @@ pub const File = struct {...@@ -840,10 +840,37 @@ pub const File = struct {
840 /// TODO: integrate with async I/O840 /// TODO: integrate with async I/O
841 pub fn setLock(file: File, lock: Lock, non_blocking: bool) SetLockError!void {841 pub fn setLock(file: File, lock: Lock, non_blocking: bool) SetLockError!void {
842 if (is_windows) {842 if (is_windows) {
843 @compileError("TODO implement fs.File.setLock for Windows");843 const range_off: windows.LARGE_INTEGER = 0;
844 const range_len: windows.LARGE_INTEGER = 1;
845 const exclusive = switch (lock) {
846 .None => return windows.UnlockFile(
847 file.handle,
848 null,
849 &range_off,
850 &range_len,
851 null,
852 ) catch |err| switch (err) {
853 error.RangeNotLocked => return,
854 else => |e| return e,
855 },
856 .Shared => false,
857 .Exclusive => true,
858 };
859 return windows.LockFile(
860 file.handle,
861 null,
862 null,
863 null,
864 null,
865 &range_off,
866 &range_len,
867 null,
868 @boolToInt(non_blocking),
869 @boolToInt(exclusive),
870 );
844 }871 }
845 const non_blocking_flag = if (non_blocking) os.LOCK_NB else @as(i32, 0);872 const non_blocking_flag = if (non_blocking) os.LOCK_NB else @as(i32, 0);
846 try os.flock(file.handle, switch (lock) {873 return os.flock(file.handle, switch (lock) {
847 .None => os.LOCK_UN,874 .None => os.LOCK_UN,
848 .Shared => os.LOCK_SH | non_blocking_flag,875 .Shared => os.LOCK_SH | non_blocking_flag,
849 .Exclusive => os.LOCK_EX | non_blocking_flag,876 .Exclusive => os.LOCK_EX | non_blocking_flag,
lib/std/os/windows.zig+56
...@@ -1679,6 +1679,62 @@ pub fn SetFileTime(...@@ -1679,6 +1679,62 @@ pub fn SetFileTime(
1679 }1679 }
1680}1680}
16811681
1682pub const LockFileError = error{
1683 SystemResources,
1684 WouldBlock,
1685} || std.os.UnexpectedError;
1686
1687pub fn LockFile(
1688 FileHandle: HANDLE,
1689 Event: ?HANDLE,
1690 ApcRoutine: ?*IO_APC_ROUTINE,
1691 ApcContext: ?*c_void,
1692 IoStatusBlock: ?*IO_STATUS_BLOCK,
1693 ByteOffset: *const LARGE_INTEGER,
1694 Length: *const LARGE_INTEGER,
1695 Key: ?*ULONG,
1696 FailImmediately: BOOLEAN,
1697 ExclusiveLock: BOOLEAN,
1698) !void {
1699 const rc = ntdll.NtLockFile(
1700 FileHandle,
1701 Event,
1702 ApcRoutine,
1703 ApcContext,
1704 IoStatusBlock,
1705 ByteOffset,
1706 Length,
1707 Key,
1708 FailImmediately,
1709 ExclusiveLock,
1710 );
1711 switch (rc) {
1712 .SUCCESS => return,
1713 .INSUFFICIENT_RESOURCES => return error.SystemResources,
1714 .LOCK_NOT_GRANTED => return error.WouldBlock,
1715 else => return unexpectedStatus(rc),
1716 }
1717}
1718
1719pub const UnlockFileError = error{
1720 RangeNotLocked,
1721} || std.os.UnexpectedError;
1722
1723pub fn UnlockFile(
1724 FileHandle: HANDLE,
1725 IoStatusBlock: ?*IO_STATUS_BLOCK,
1726 ByteOffset: *const LARGE_INTEGER,
1727 Length: *const LARGE_INTEGER,
1728 Key: ?*ULONG,
1729) !void {
1730 const rc = ntdll.NtUnlockFile(FileHandle, IoStatusBlock, ByteOffset, Length, Key);
1731 switch (rc) {
1732 .SUCCESS => return,
1733 .RANGE_NOT_LOCKED => return error.RangeNotLocked,
1734 else => return unexpectedStatus(rc),
1735 }
1736}
1737
1682pub fn teb() *TEB {1738pub fn teb() *TEB {
1683 return switch (builtin.target.cpu.arch) {1739 return switch (builtin.target.cpu.arch) {
1684 .i386 => asm volatile (1740 .i386 => asm volatile (
lib/std/os/windows/ntdll.zig+21
...@@ -139,3 +139,24 @@ pub extern "NtDll" fn RtlWaitOnAddress(...@@ -139,3 +139,24 @@ pub extern "NtDll" fn RtlWaitOnAddress(
139 AddressSize: SIZE_T,139 AddressSize: SIZE_T,
140 Timeout: ?*const LARGE_INTEGER,140 Timeout: ?*const LARGE_INTEGER,
141) callconv(WINAPI) NTSTATUS;141) callconv(WINAPI) NTSTATUS;
142
143pub extern "NtDll" fn NtLockFile(
144 FileHandle: HANDLE,
145 Event: ?HANDLE,
146 ApcRoutine: ?*IO_APC_ROUTINE,
147 ApcContext: ?*c_void,
148 IoStatusBlock: ?*IO_STATUS_BLOCK,
149 ByteOffset: *const LARGE_INTEGER,
150 Length: *const LARGE_INTEGER,
151 Key: ?*ULONG,
152 FailImmediately: BOOLEAN,
153 ExclusiveLock: BOOLEAN,
154) callconv(WINAPI) NTSTATUS;
155
156pub extern "NtDll" fn NtUnlockFile(
157 FileHandle: HANDLE,
158 IoStatusBlock: ?*IO_STATUS_BLOCK,
159 ByteOffset: *const LARGE_INTEGER,
160 Length: *const LARGE_INTEGER,
161 Key: ?*ULONG,
162) callconv(WINAPI) NTSTATUS;