| author | |
| committer | |
| log | 488f68069ba0a81f46a5afe721b908cfd3c61f76 |
| tree | 4f2316eefbe164a0b42864dbb0d2a3c128ed7417 |
| parent | 3d7ae63c6f0b01456a411b31bad2322166634868 |
3 files changed, 106 insertions(+), 2 deletions(-)
lib/std/fs/file.zig+29-2| ... | ... | @@ -840,10 +840,37 @@ pub const File = struct { |
| 840 | 840 | /// TODO: integrate with async I/O |
| 841 | 841 | pub fn setLock(file: File, lock: Lock, non_blocking: bool) SetLockError!void { |
| 842 | 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 | 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 | 874 | .None => os.LOCK_UN, |
| 848 | 875 | .Shared => os.LOCK_SH | non_blocking_flag, |
| 849 | 876 | .Exclusive => os.LOCK_EX | non_blocking_flag, |
lib/std/os/windows.zig+56| ... | ... | @@ -1679,6 +1679,62 @@ pub fn SetFileTime( |
| 1679 | 1679 | } |
| 1680 | 1680 | } |
| 1681 | 1681 | |
| 1682 | pub const LockFileError = error{ | |
| 1683 | SystemResources, | |
| 1684 | WouldBlock, | |
| 1685 | } || std.os.UnexpectedError; | |
| 1686 | ||
| 1687 | pub 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 | ||
| 1719 | pub const UnlockFileError = error{ | |
| 1720 | RangeNotLocked, | |
| 1721 | } || std.os.UnexpectedError; | |
| 1722 | ||
| 1723 | pub 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 | ||
| 1682 | 1738 | pub fn teb() *TEB { |
| 1683 | 1739 | return switch (builtin.target.cpu.arch) { |
| 1684 | 1740 | .i386 => asm volatile ( |
lib/std/os/windows/ntdll.zig+21| ... | ... | @@ -139,3 +139,24 @@ pub extern "NtDll" fn RtlWaitOnAddress( |
| 139 | 139 | AddressSize: SIZE_T, |
| 140 | 140 | Timeout: ?*const LARGE_INTEGER, |
| 141 | 141 | ) callconv(WINAPI) NTSTATUS; |
| 142 | ||
| 143 | pub 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 | ||
| 156 | pub 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; |