mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
116 lines
3.8 KiB
Zig
116 lines
3.8 KiB
Zig
//! This namespace provides an implementation of the Robust Jobserver protocol:
|
|
//! https://codeberg.org/mlugg/robust-jobserver/
|
|
//!
|
|
//! `Client` and `Server` currently both support the `sysvsem` and `win32pipe`
|
|
//! communication methods, meaning this implementation is usable on most POSIX
|
|
//! targets and on Windows.
|
|
|
|
pub const Client = @import("job/Client.zig");
|
|
pub const Server = @import("job/Server.zig");
|
|
|
|
pub const Method = enum { sysvsem, win32pipe };
|
|
|
|
pub const sysv_sem = struct {
|
|
pub const supported = switch (builtin.os.tag) {
|
|
.linux,
|
|
.illumos,
|
|
.haiku,
|
|
|
|
.freebsd,
|
|
.netbsd,
|
|
.openbsd,
|
|
.dragonfly,
|
|
|
|
.driverkit,
|
|
.ios,
|
|
.maccatalyst,
|
|
.macos,
|
|
.tvos,
|
|
.visionos,
|
|
.watchos,
|
|
=> true,
|
|
|
|
else => false,
|
|
};
|
|
|
|
/// `semget(IPC_PRIVATE, 1, 0o777)`
|
|
pub fn create() error{ SystemResources, Unexpected }!i32 {
|
|
const res = system.create();
|
|
switch (std.posix.errno(res)) {
|
|
.SUCCESS => return @intCast(res),
|
|
.NOMEM => return error.SystemResources,
|
|
.NOSPC => return error.SystemResources,
|
|
else => |e| return std.posix.unexpectedErrno(e),
|
|
}
|
|
}
|
|
/// `semctl(id, 0, SETVAL, n)`
|
|
pub fn setValue(id: i32, n: u32) error{Unexpected}!void {
|
|
switch (std.posix.errno(system.setValue(id, n))) {
|
|
.SUCCESS => return,
|
|
else => |e| return std.posix.unexpectedErrno(e),
|
|
}
|
|
}
|
|
/// `semop(id, &.{.{ .sem_num = 0, .sem_op = delta, .sem_flg = SEM_UNDO }})`
|
|
pub fn modify(id: i32, delta: i16) error{
|
|
InvalidSemaphore,
|
|
AccessDenied,
|
|
SystemResources,
|
|
/// A signal interrupted a blocked call to `modify`.
|
|
/// This allows the caller to implement cancelation.
|
|
Interrupted,
|
|
Unexpected,
|
|
}!void {
|
|
while (true) {
|
|
switch (std.posix.errno(system.modify(id, delta))) {
|
|
.SUCCESS => return,
|
|
.ACCES => return error.AccessDenied,
|
|
.FBIG => return error.InvalidSemaphore,
|
|
.IDRM => return error.InvalidSemaphore,
|
|
.INTR => return error.Interrupted,
|
|
.INVAL => return error.InvalidSemaphore,
|
|
.NOMEM => return error.SystemResources,
|
|
.RANGE => return error.InvalidSemaphore,
|
|
else => |e| return std.posix.unexpectedErrno(e),
|
|
}
|
|
}
|
|
}
|
|
|
|
const system = if (builtin.link_libc) struct {
|
|
fn create() c_int {
|
|
return std.c.semget(.IPC_PRIVATE, 1, 0o777);
|
|
}
|
|
fn setValue(id: i32, n: u32) c_int {
|
|
return std.c.semctl(id, 0, std.posix.SETVAL, n);
|
|
}
|
|
fn modify(id: i32, delta: i16) c_int {
|
|
var ops: [1]std.posix.sembuf = .{.{
|
|
.sem_num = 0,
|
|
.sem_op = delta,
|
|
.sem_flg = std.posix.SEM_UNDO,
|
|
}};
|
|
return std.c.semop(id, &ops, ops.len);
|
|
}
|
|
} else switch (builtin.os.tag) {
|
|
.linux => struct {
|
|
fn create() usize {
|
|
const key: std.posix.key_t = .IPC_PRIVATE;
|
|
return std.os.linux.syscall3(.semget, @intFromEnum(key), 1, 0o777);
|
|
}
|
|
fn setValue(id: i32, n: u32) usize {
|
|
return std.os.linux.syscall4(.semctl, @intCast(id), 0, std.posix.SETVAL, n);
|
|
}
|
|
fn modify(id: i32, delta: i16) usize {
|
|
var ops: [1]std.posix.sembuf = .{.{
|
|
.sem_num = 0,
|
|
.sem_op = delta,
|
|
.sem_flg = std.posix.SEM_UNDO,
|
|
}};
|
|
return std.os.linux.syscall3(.semop, @intCast(id), @intFromPtr(&ops), ops.len);
|
|
}
|
|
},
|
|
else => unreachable,
|
|
};
|
|
};
|
|
|
|
const builtin = @import("builtin");
|
|
const std = @import("std.zig");
|