mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
std.Io.Threaded: use musl's beautiful pthread_cancel semantics
This commit is contained in:
parent
d60760d61e
commit
39ac40209b
3 changed files with 121 additions and 83 deletions
|
|
@ -3,6 +3,7 @@ const Threaded = @This();
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const native_os = builtin.os.tag;
|
const native_os = builtin.os.tag;
|
||||||
const is_windows = native_os == .windows;
|
const is_windows = native_os == .windows;
|
||||||
|
const is_musl = builtin.link_libc and builtin.abi.isMusl();
|
||||||
const windows = std.os.windows;
|
const windows = std.os.windows;
|
||||||
const ws2_32 = std.os.windows.ws2_32;
|
const ws2_32 = std.os.windows.ws2_32;
|
||||||
const is_debug = builtin.mode == .Debug;
|
const is_debug = builtin.mode == .Debug;
|
||||||
|
|
@ -111,7 +112,7 @@ const Thread = struct {
|
||||||
@atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);
|
@atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);
|
||||||
return error.Canceled;
|
return error.Canceled;
|
||||||
},
|
},
|
||||||
.acknowledged => unreachable,
|
.acknowledged => return,
|
||||||
_ => unreachable,
|
_ => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -128,6 +129,13 @@ const Thread = struct {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn endSyscallCanceled(thread: *Thread) Io.Cancelable {
|
||||||
|
if (thread.current_closure) |closure| {
|
||||||
|
@atomicStore(CancelStatus, &closure.cancel_status, .acknowledged, .release);
|
||||||
|
}
|
||||||
|
return error.Canceled;
|
||||||
|
}
|
||||||
|
|
||||||
fn currentSignalId() SignalId {
|
fn currentSignalId() SignalId {
|
||||||
return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();
|
return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();
|
||||||
}
|
}
|
||||||
|
|
@ -197,6 +205,13 @@ const Closure = struct {
|
||||||
.none, .acknowledged, .requested => return,
|
.none, .acknowledged, .requested => return,
|
||||||
.signal_id => |signal_id| signal_id,
|
.signal_id => |signal_id| signal_id,
|
||||||
};
|
};
|
||||||
|
// Musl has an undocumented extension that makes pthread_cancel have the useful, desired
|
||||||
|
// behavior of causing the next syscall to return ECANCELED.
|
||||||
|
if (is_musl) {
|
||||||
|
_ = std.c.pthread_cancel(signal_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// The task will enter a blocking syscall before checking for cancellation again.
|
// The task will enter a blocking syscall before checking for cancellation again.
|
||||||
// We can send a signal to interrupt the syscall, but if it arrives before
|
// We can send a signal to interrupt the syscall, but if it arrives before
|
||||||
// the syscall instruction, it will be missed. Therefore, this code tries
|
// the syscall instruction, it will be missed. Therefore, this code tries
|
||||||
|
|
@ -218,8 +233,7 @@ const Closure = struct {
|
||||||
|
|
||||||
for (0..max_attempts) |attempt_index| {
|
for (0..max_attempts) |attempt_index| {
|
||||||
if (std.Thread.use_pthreads) {
|
if (std.Thread.use_pthreads) {
|
||||||
const rc = std.c.pthread_kill(signal_id, .IO);
|
if (std.c.pthread_kill(signal_id, .IO) != 0) return;
|
||||||
if (is_debug) assert(rc == 0);
|
|
||||||
} else if (native_os == .linux) {
|
} else if (native_os == .linux) {
|
||||||
const pid: posix.pid_t = p: {
|
const pid: posix.pid_t = p: {
|
||||||
const cached_pid = @atomicLoad(Pid, &t.pid, .monotonic);
|
const cached_pid = @atomicLoad(Pid, &t.pid, .monotonic);
|
||||||
|
|
@ -228,7 +242,7 @@ const Closure = struct {
|
||||||
@atomicStore(Pid, &t.pid, @enumFromInt(pid), .monotonic);
|
@atomicStore(Pid, &t.pid, @enumFromInt(pid), .monotonic);
|
||||||
break :p pid;
|
break :p pid;
|
||||||
};
|
};
|
||||||
_ = std.os.linux.tgkill(pid, @bitCast(signal_id), .IO);
|
if (std.os.linux.tgkill(pid, @bitCast(signal_id), .IO) != 0) return;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -354,6 +368,11 @@ fn worker(t: *Threaded) void {
|
||||||
while (true) {
|
while (true) {
|
||||||
while (t.run_queue.popFirst()) |closure_node| {
|
while (t.run_queue.popFirst()) |closure_node| {
|
||||||
t.mutex.unlock();
|
t.mutex.unlock();
|
||||||
|
|
||||||
|
// Musl has an undocumented extension that makes pthread_cancel have the useful, desired
|
||||||
|
// behavior of causing the next syscall to return ECANCELED.
|
||||||
|
if (is_musl) assert(std.c.pthread_setcancelstate(.MASKED, null) == .SUCCESS);
|
||||||
|
|
||||||
const closure: *Closure = @fieldParentPtr("node", closure_node);
|
const closure: *Closure = @fieldParentPtr("node", closure_node);
|
||||||
closure.start(closure, t);
|
closure.start(closure, t);
|
||||||
t.mutex.lock();
|
t.mutex.lock();
|
||||||
|
|
@ -1198,10 +1217,10 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.PERM => return error.PermissionDenied,
|
.PERM => return error.PermissionDenied,
|
||||||
|
|
@ -1241,25 +1260,29 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: I
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
.CANCELED => return error.Canceled,
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
|
else => |e| {
|
||||||
.ACCES => return error.AccessDenied,
|
current_thread.endSyscall();
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
switch (e) {
|
||||||
.PERM => return error.PermissionDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.DQUOT => return error.DiskQuota,
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.EXIST => return error.PathAlreadyExists,
|
.PERM => return error.PermissionDenied,
|
||||||
.FAULT => |err| return errnoBug(err),
|
.DQUOT => return error.DiskQuota,
|
||||||
.LOOP => return error.SymLinkLoop,
|
.EXIST => return error.PathAlreadyExists,
|
||||||
.MLINK => return error.LinkQuotaExceeded,
|
.FAULT => |err| return errnoBug(err),
|
||||||
.NAMETOOLONG => return error.NameTooLong,
|
.LOOP => return error.SymLinkLoop,
|
||||||
.NOENT => return error.FileNotFound,
|
.MLINK => return error.LinkQuotaExceeded,
|
||||||
.NOMEM => return error.SystemResources,
|
.NAMETOOLONG => return error.NameTooLong,
|
||||||
.NOSPC => return error.NoSpaceLeft,
|
.NOENT => return error.FileNotFound,
|
||||||
.NOTDIR => return error.NotDir,
|
.NOMEM => return error.SystemResources,
|
||||||
.ROFS => return error.ReadOnlyFileSystem,
|
.NOSPC => return error.NoSpaceLeft,
|
||||||
.NOTCAPABLE => return error.AccessDenied,
|
.NOTDIR => return error.NotDir,
|
||||||
.ILSEQ => return error.BadPathName,
|
.ROFS => return error.ReadOnlyFileSystem,
|
||||||
else => |err| return posix.unexpectedErrno(err),
|
.NOTCAPABLE => return error.AccessDenied,
|
||||||
|
.ILSEQ => return error.BadPathName,
|
||||||
|
else => |err| return posix.unexpectedErrno(err),
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1503,10 +1526,10 @@ fn dirStatPathLinux(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
|
|
@ -1549,10 +1572,10 @@ fn dirStatPathPosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
|
|
@ -1610,10 +1633,10 @@ fn dirStatPathWasi(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
|
|
@ -1656,10 +1679,10 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
|
|
@ -1695,10 +1718,10 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ACCES => |err| return errnoBug(err),
|
.ACCES => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
|
|
@ -1781,10 +1804,10 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
|
|
@ -1833,10 +1856,10 @@ fn dirAccessPosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.PERM => return error.PermissionDenied,
|
.PERM => return error.PermissionDenied,
|
||||||
.ROFS => return error.ReadOnlyFileSystem,
|
.ROFS => return error.ReadOnlyFileSystem,
|
||||||
|
|
@ -1883,10 +1906,10 @@ fn dirAccessWasi(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
|
|
@ -2030,10 +2053,10 @@ fn dirCreateFilePosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.INVAL => return error.BadPathName,
|
.INVAL => return error.BadPathName,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
|
|
@ -2085,10 +2108,10 @@ fn dirCreateFilePosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.INVAL => |err| return errnoBug(err), // invalid parameters
|
.INVAL => |err| return errnoBug(err), // invalid parameters
|
||||||
.NOLCK => return error.SystemResources,
|
.NOLCK => return error.SystemResources,
|
||||||
|
|
@ -2240,10 +2263,10 @@ fn dirCreateFileWasi(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.INVAL => return error.BadPathName,
|
.INVAL => return error.BadPathName,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
|
|
@ -2334,10 +2357,10 @@ fn dirOpenFilePosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.INVAL => return error.BadPathName,
|
.INVAL => return error.BadPathName,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
|
|
@ -2388,10 +2411,10 @@ fn dirOpenFilePosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.INVAL => |err| return errnoBug(err), // invalid parameters
|
.INVAL => |err| return errnoBug(err), // invalid parameters
|
||||||
.NOLCK => return error.SystemResources,
|
.NOLCK => return error.SystemResources,
|
||||||
|
|
@ -2417,6 +2440,7 @@ fn dirOpenFilePosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |err| {
|
else => |err| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
return posix.unexpectedErrno(err);
|
return posix.unexpectedErrno(err);
|
||||||
|
|
@ -2437,6 +2461,7 @@ fn dirOpenFilePosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |err| {
|
else => |err| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
return posix.unexpectedErrno(err);
|
return posix.unexpectedErrno(err);
|
||||||
|
|
@ -2635,10 +2660,10 @@ fn dirOpenFileWasi(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
|
|
@ -2719,10 +2744,10 @@ fn dirOpenDirPosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.INVAL => return error.BadPathName,
|
.INVAL => return error.BadPathName,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
|
|
@ -2772,10 +2797,10 @@ fn dirOpenDirHaiku(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
|
|
@ -2917,10 +2942,10 @@ fn dirOpenDirWasi(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.INVAL => return error.BadPathName,
|
.INVAL => return error.BadPathName,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
|
|
@ -2984,10 +3009,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.BADF => return error.NotOpenForReading, // File operation on directory.
|
.BADF => return error.NotOpenForReading, // File operation on directory.
|
||||||
|
|
@ -3018,10 +3043,10 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.SRCH => return error.ProcessNotFound,
|
.SRCH => return error.ProcessNotFound,
|
||||||
|
|
@ -3104,10 +3129,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.AGAIN => |err| return errnoBug(err),
|
.AGAIN => |err| return errnoBug(err),
|
||||||
|
|
@ -3142,10 +3167,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.SRCH => return error.ProcessNotFound,
|
.SRCH => return error.ProcessNotFound,
|
||||||
|
|
@ -3244,10 +3269,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.INVAL => return error.Unseekable,
|
.INVAL => return error.Unseekable,
|
||||||
.OVERFLOW => return error.Unseekable,
|
.OVERFLOW => return error.Unseekable,
|
||||||
|
|
@ -3277,10 +3302,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.INVAL => return error.Unseekable,
|
.INVAL => return error.Unseekable,
|
||||||
.OVERFLOW => return error.Unseekable,
|
.OVERFLOW => return error.Unseekable,
|
||||||
|
|
@ -3306,10 +3331,10 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.INVAL => return error.Unseekable,
|
.INVAL => return error.Unseekable,
|
||||||
.OVERFLOW => return error.Unseekable,
|
.OVERFLOW => return error.Unseekable,
|
||||||
|
|
@ -3430,7 +3455,8 @@ fn nowWasi(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
|
||||||
const sleep = switch (native_os) {
|
const sleep = switch (native_os) {
|
||||||
.windows => sleepWindows,
|
.windows => sleepWindows,
|
||||||
.wasi => sleepWasi,
|
.wasi => sleepWasi,
|
||||||
.linux => sleepLinux,
|
// Since we use musl's pthread_cancel, it's important that all the syscalls go through libc.
|
||||||
|
.linux => if (is_musl) sleepPosix else sleepLinux,
|
||||||
else => sleepPosix,
|
else => sleepPosix,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -3462,10 +3488,10 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => return error.UnsupportedClock,
|
.INVAL => return error.UnsupportedClock,
|
||||||
else => |err| return posix.unexpectedErrno(err),
|
else => |err| return posix.unexpectedErrno(err),
|
||||||
}
|
}
|
||||||
|
|
@ -3540,11 +3566,9 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
else => {
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
// This prong handles success as well as unexpected errors.
|
// This prong handles success as well as unexpected errors.
|
||||||
current_thread.endSyscall();
|
else => return current_thread.endSyscall(),
|
||||||
return;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3616,10 +3640,10 @@ fn netListenIpPosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ADDRINUSE => return error.AddressInUse,
|
.ADDRINUSE => return error.AddressInUse,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
else => |err| return posix.unexpectedErrno(err),
|
else => |err| return posix.unexpectedErrno(err),
|
||||||
|
|
@ -3777,10 +3801,10 @@ fn netListenUnixPosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ADDRINUSE => return error.AddressInUse,
|
.ADDRINUSE => return error.AddressInUse,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
else => |err| return posix.unexpectedErrno(err),
|
else => |err| return posix.unexpectedErrno(err),
|
||||||
|
|
@ -3901,10 +3925,10 @@ fn posixBindUnix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.ADDRINUSE => return error.AddressInUse,
|
.ADDRINUSE => return error.AddressInUse,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
|
|
@ -3946,10 +3970,10 @@ fn posixBind(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ADDRINUSE => return error.AddressInUse,
|
.ADDRINUSE => return error.AddressInUse,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.INVAL => |err| return errnoBug(err), // invalid parameters
|
.INVAL => |err| return errnoBug(err), // invalid parameters
|
||||||
|
|
@ -3982,10 +4006,10 @@ fn posixConnect(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ADDRNOTAVAIL => return error.AddressUnavailable,
|
.ADDRNOTAVAIL => return error.AddressUnavailable,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.AGAIN, .INPROGRESS => return error.WouldBlock,
|
.AGAIN, .INPROGRESS => return error.WouldBlock,
|
||||||
|
|
@ -4029,10 +4053,10 @@ fn posixConnectUnix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.AGAIN => return error.WouldBlock,
|
.AGAIN => return error.WouldBlock,
|
||||||
.INPROGRESS => return error.WouldBlock,
|
.INPROGRESS => return error.WouldBlock,
|
||||||
|
|
@ -4074,10 +4098,10 @@ fn posixGetSockName(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.INVAL => |err| return errnoBug(err), // invalid parameters
|
.INVAL => |err| return errnoBug(err), // invalid parameters
|
||||||
|
|
@ -4142,10 +4166,10 @@ fn setSocketOption(current_thread: *Thread, fd: posix.fd_t, level: i32, opt_name
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.NOTSOCK => |err| return errnoBug(err),
|
.NOTSOCK => |err| return errnoBug(err),
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
|
|
@ -4472,12 +4496,10 @@ fn openSocketPosix(
|
||||||
switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
|
switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
|
||||||
.SUCCESS => break,
|
.SUCCESS => break,
|
||||||
.INTR => continue,
|
.INTR => continue,
|
||||||
else => |e| {
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
|
else => |err| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
return posix.unexpectedErrno(err);
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
else => |err| return posix.unexpectedErrno(err),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -4488,10 +4510,10 @@ fn openSocketPosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.INVAL => return error.ProtocolUnsupportedBySystem,
|
.INVAL => return error.ProtocolUnsupportedBySystem,
|
||||||
.MFILE => return error.ProcessFdQuotaExceeded,
|
.MFILE => return error.ProcessFdQuotaExceeded,
|
||||||
|
|
@ -4590,10 +4612,10 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.AGAIN => |err| return errnoBug(err),
|
.AGAIN => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
.CONNABORTED => return error.ConnectionAborted,
|
.CONNABORTED => return error.ConnectionAborted,
|
||||||
|
|
@ -4699,10 +4721,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.AGAIN => |err| return errnoBug(err),
|
.AGAIN => |err| return errnoBug(err),
|
||||||
|
|
@ -4732,10 +4754,10 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.AGAIN => |err| return errnoBug(err),
|
.AGAIN => |err| return errnoBug(err),
|
||||||
|
|
@ -4968,10 +4990,10 @@ fn netSendOne(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.ALREADY => return error.FastOpenAlreadyInProgress,
|
.ALREADY => return error.FastOpenAlreadyInProgress,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
|
|
@ -5045,10 +5067,10 @@ fn netSendMany(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.AGAIN => |err| return errnoBug(err),
|
.AGAIN => |err| return errnoBug(err),
|
||||||
.ALREADY => return error.FastOpenAlreadyInProgress,
|
.ALREADY => return error.FastOpenAlreadyInProgress,
|
||||||
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
.BADF => |err| return errnoBug(err), // File descriptor used after closed.
|
||||||
|
|
@ -5178,7 +5200,7 @@ fn netReceivePosix(
|
||||||
continue :recv;
|
continue :recv;
|
||||||
},
|
},
|
||||||
.INTR => continue,
|
.INTR => continue,
|
||||||
.CANCELED => return .{ error.Canceled, message_i },
|
.CANCELED => return .{ current_thread.endSyscallCanceled(), message_i },
|
||||||
|
|
||||||
.FAULT => |err| return .{ errnoBug(err), message_i },
|
.FAULT => |err| return .{ errnoBug(err), message_i },
|
||||||
.INVAL => |err| return .{ errnoBug(err), message_i },
|
.INVAL => |err| return .{ errnoBug(err), message_i },
|
||||||
|
|
@ -5187,7 +5209,7 @@ fn netReceivePosix(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.INTR => continue,
|
.INTR => continue,
|
||||||
.CANCELED => return .{ error.Canceled, message_i },
|
.CANCELED => return .{ current_thread.endSyscallCanceled(), message_i },
|
||||||
|
|
||||||
.BADF => |err| return .{ errnoBug(err), message_i },
|
.BADF => |err| return .{ errnoBug(err), message_i },
|
||||||
.NFILE => return .{ error.SystemFdQuotaExceeded, message_i },
|
.NFILE => return .{ error.SystemFdQuotaExceeded, message_i },
|
||||||
|
|
@ -5306,10 +5328,10 @@ fn netWritePosix(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.ACCES => |err| return errnoBug(err),
|
.ACCES => |err| return errnoBug(err),
|
||||||
.AGAIN => |err| return errnoBug(err),
|
.AGAIN => |err| return errnoBug(err),
|
||||||
.ALREADY => return error.FastOpenAlreadyInProgress,
|
.ALREADY => return error.FastOpenAlreadyInProgress,
|
||||||
|
|
@ -5405,7 +5427,7 @@ fn netWriteWindows(
|
||||||
};
|
};
|
||||||
switch (wsa_error) {
|
switch (wsa_error) {
|
||||||
.EINTR => continue,
|
.EINTR => continue,
|
||||||
.ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
|
.ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return current_thread.endSyscallCanceled(),
|
||||||
.NOTINITIALISED => {
|
.NOTINITIALISED => {
|
||||||
try initializeWsa(t);
|
try initializeWsa(t);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -5517,10 +5539,10 @@ fn netInterfaceNameResolve(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
switch (e) {
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
.INVAL => |err| return errnoBug(err), // Bad parameters.
|
.INVAL => |err| return errnoBug(err), // Bad parameters.
|
||||||
.NOTTY => |err| return errnoBug(err),
|
.NOTTY => |err| return errnoBug(err),
|
||||||
.NXIO => |err| return errnoBug(err),
|
.NXIO => |err| return errnoBug(err),
|
||||||
|
|
@ -5818,12 +5840,10 @@ fn netLookupFallible(
|
||||||
try current_thread.checkCancel();
|
try current_thread.checkCancel();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
.CANCELED => return current_thread.endSyscallCanceled(),
|
||||||
else => |e| {
|
else => |e| {
|
||||||
current_thread.endSyscall();
|
current_thread.endSyscall();
|
||||||
switch (e) {
|
return posix.unexpectedErrno(e);
|
||||||
.CANCELED => return error.Canceled,
|
|
||||||
else => |inner| return posix.unexpectedErrno(inner),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
else => |e| {
|
else => |e| {
|
||||||
|
|
|
||||||
|
|
@ -10881,6 +10881,23 @@ pub extern "c" fn pthread_create(
|
||||||
start_routine: *const fn (?*anyopaque) callconv(.c) ?*anyopaque,
|
start_routine: *const fn (?*anyopaque) callconv(.c) ?*anyopaque,
|
||||||
noalias arg: ?*anyopaque,
|
noalias arg: ?*anyopaque,
|
||||||
) E;
|
) E;
|
||||||
|
pub const pthread_cancelstate = switch (native_os) {
|
||||||
|
.ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => enum(c_int) {
|
||||||
|
ENABLE = 1,
|
||||||
|
DISABLE = 0,
|
||||||
|
},
|
||||||
|
.linux => if (native_abi.isMusl()) enum(c_int) {
|
||||||
|
ENABLE = 0,
|
||||||
|
DISABLE = 1,
|
||||||
|
MASKED = 2,
|
||||||
|
} else if (native_abi.isGnu()) enum(c_int) {
|
||||||
|
ENABLE = 0,
|
||||||
|
DISABLE = 1,
|
||||||
|
},
|
||||||
|
else => void,
|
||||||
|
};
|
||||||
|
pub extern "c" fn pthread_setcancelstate(pthread_cancelstate, ?*pthread_cancelstate) E;
|
||||||
|
pub extern "c" fn pthread_cancel(pthread_t) E;
|
||||||
pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) E;
|
pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) E;
|
||||||
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) E;
|
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) E;
|
||||||
pub extern "c" fn pthread_attr_setstacksize(attr: *pthread_attr_t, stacksize: usize) E;
|
pub extern "c" fn pthread_attr_setstacksize(attr: *pthread_attr_t, stacksize: usize) E;
|
||||||
|
|
|
||||||
|
|
@ -1360,6 +1360,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
|
||||||
.PIPE => return error.BrokenPipe,
|
.PIPE => return error.BrokenPipe,
|
||||||
.CONNRESET => return error.ConnectionResetByPeer,
|
.CONNRESET => return error.ConnectionResetByPeer,
|
||||||
.BUSY => return error.DeviceBusy,
|
.BUSY => return error.DeviceBusy,
|
||||||
|
.CANCELED => return error.Canceled,
|
||||||
else => |err| return unexpectedErrno(err),
|
else => |err| return unexpectedErrno(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue