feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.fileTryLock
fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!bool
File
Code
fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!bool {
if (native_os == .wasi) return error.FileLocksUnsupported;
const t: *Threaded = @ptrCast(@alignCast(userdata));
_ = t;
if (is_windows) {
const exclusive = switch (lock) {
.none => {
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
while (true) switch (windows.ntdll.NtUnlockFile(
file.handle,
&io_status_block,
&windows_lock_range_off,
&windows_lock_range_len,
0,
)) {
.SUCCESS => return true,
.CANCELLED => continue,
.RANGE_NOT_LOCKED => return false,
.ACCESS_VIOLATION => |err| return windows.statusBug(err),
else => |status| return windows.unexpectedStatus(status),
};
},
.shared => false,
.exclusive => true,
};
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
const syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtLockFile(
file.handle,
null,
null,
null,
&io_status_block,
&windows_lock_range_off,
&windows_lock_range_len,
null,
.TRUE,
.fromBool(exclusive),
)) {
.SUCCESS => {
syscall.finish();
return true;
},
.LOCK_NOT_GRANTED => {
syscall.finish();
return false;
},
.CANCELLED => {
try syscall.checkCancel();
continue;
},
.INSUFFICIENT_RESOURCES => return syscall.fail(error.SystemResources),
.ACCESS_VIOLATION => |err| return syscall.ntstatusBug(err),
else => |status| return syscall.unexpectedNtstatus(status),
};
}
const operation: i32 = switch (lock) {
.none => posix.LOCK.UN,
.shared => posix.LOCK.SH | posix.LOCK.NB,
.exclusive => posix.LOCK.EX | posix.LOCK.NB,
};
const syscall: Syscall = try .start();
while (true) {
switch (posix.errno(posix.system.flock(file.handle, operation))) {
.SUCCESS => {
syscall.finish();
return true;
},
.INTR => {
try syscall.checkCancel();
continue;
},
.AGAIN => {
syscall.finish();
return false;
},
else => |e| {
syscall.finish();
switch (e) {
.BADF => |err| return errnoBug(err),
.INVAL => |err| return errnoBug(err),
.NOLCK => return error.SystemResources,
.OPNOTSUPP => return error.FileLocksUnsupported,
else => |err| return posix.unexpectedErrno(err),
}
},
}
}
}