mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
introduce std.process.raiseFileDescriptorLimit
This commit is contained in:
parent
a72292513e
commit
16d368d0d2
2 changed files with 48 additions and 51 deletions
|
|
@ -1742,3 +1742,49 @@ pub fn cleanExit() void {
|
|||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Raise the open file descriptor limit.
|
||||
///
|
||||
/// On some systems, this raises the limit before seeing ProcessFdQuotaExceeded
|
||||
/// errors. On other systems, this does nothing.
|
||||
pub fn raiseFileDescriptorLimit() void {
|
||||
const have_rlimit = switch (native_os) {
|
||||
.windows, .wasi => false,
|
||||
else => true,
|
||||
};
|
||||
if (!have_rlimit) return;
|
||||
|
||||
var lim = posix.getrlimit(.NOFILE) catch return; // Oh well; we tried.
|
||||
if (native_os.isDarwin()) {
|
||||
// On Darwin, `NOFILE` is bounded by a hardcoded value `OPEN_MAX`.
|
||||
// According to the man pages for setrlimit():
|
||||
// setrlimit() now returns with errno set to EINVAL in places that historically succeeded.
|
||||
// It no longer accepts "rlim_cur = RLIM.INFINITY" for RLIM.NOFILE.
|
||||
// Use "rlim_cur = min(OPEN_MAX, rlim_max)".
|
||||
lim.max = @min(std.c.OPEN_MAX, lim.max);
|
||||
}
|
||||
if (lim.cur == lim.max) return;
|
||||
|
||||
// Do a binary search for the limit.
|
||||
var min: posix.rlim_t = lim.cur;
|
||||
var max: posix.rlim_t = 1 << 20;
|
||||
// But if there's a defined upper bound, don't search, just set it.
|
||||
if (lim.max != posix.RLIM.INFINITY) {
|
||||
min = lim.max;
|
||||
max = lim.max;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
lim.cur = min + @divTrunc(max - min, 2); // on freebsd rlim_t is signed
|
||||
if (posix.setrlimit(.NOFILE, lim)) |_| {
|
||||
min = lim.cur;
|
||||
} else |_| {
|
||||
max = lim.cur;
|
||||
}
|
||||
if (min + 1 >= max) break;
|
||||
}
|
||||
}
|
||||
|
||||
test raiseFileDescriptorLimit {
|
||||
raiseFileDescriptorLimit();
|
||||
}
|
||||
|
|
|
|||
53
src/main.zig
53
src/main.zig
|
|
@ -3197,7 +3197,7 @@ fn buildOutputType(
|
|||
break :b .incremental;
|
||||
};
|
||||
|
||||
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
||||
process.raiseFileDescriptorLimit();
|
||||
|
||||
const comp = Compilation.create(gpa, arena, .{
|
||||
.zig_lib_directory = zig_lib_directory,
|
||||
|
|
@ -4908,7 +4908,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
|||
.basename = exe_basename,
|
||||
};
|
||||
|
||||
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
||||
process.raiseFileDescriptorLimit();
|
||||
|
||||
var zig_lib_directory: Compilation.Directory = if (override_lib_dir) |lib_dir| .{
|
||||
.path = lib_dir,
|
||||
|
|
@ -5973,55 +5973,6 @@ fn parseCodeModel(arg: []const u8) std.builtin.CodeModel {
|
|||
fatal("unsupported machine code model: '{s}'", .{arg});
|
||||
}
|
||||
|
||||
/// Raise the open file descriptor limit. Ask and ye shall receive.
|
||||
/// For one example of why this is handy, consider the case of building musl libc.
|
||||
/// We keep a lock open for each of the object files in the form of a file descriptor
|
||||
/// until they are finally put into an archive file. This is to allow a zig-cache
|
||||
/// garbage collector to run concurrently to zig processes, and to allow multiple
|
||||
/// zig processes to run concurrently with each other, without clobbering each other.
|
||||
fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {
|
||||
const have_rlimit = switch (native_os) {
|
||||
.windows, .wasi => false,
|
||||
else => true,
|
||||
};
|
||||
if (!have_rlimit) return;
|
||||
const posix = std.posix;
|
||||
|
||||
var lim = posix.getrlimit(.NOFILE) catch return; // Oh well; we tried.
|
||||
if (native_os.isDarwin()) {
|
||||
// On Darwin, `NOFILE` is bounded by a hardcoded value `OPEN_MAX`.
|
||||
// According to the man pages for setrlimit():
|
||||
// setrlimit() now returns with errno set to EINVAL in places that historically succeeded.
|
||||
// It no longer accepts "rlim_cur = RLIM.INFINITY" for RLIM.NOFILE.
|
||||
// Use "rlim_cur = min(OPEN_MAX, rlim_max)".
|
||||
lim.max = @min(std.c.OPEN_MAX, lim.max);
|
||||
}
|
||||
if (lim.cur == lim.max) return;
|
||||
|
||||
// Do a binary search for the limit.
|
||||
var min: posix.rlim_t = lim.cur;
|
||||
var max: posix.rlim_t = 1 << 20;
|
||||
// But if there's a defined upper bound, don't search, just set it.
|
||||
if (lim.max != posix.RLIM.INFINITY) {
|
||||
min = lim.max;
|
||||
max = lim.max;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
lim.cur = min + @divTrunc(max - min, 2); // on freebsd rlim_t is signed
|
||||
if (posix.setrlimit(.NOFILE, lim)) |_| {
|
||||
min = lim.cur;
|
||||
} else |_| {
|
||||
max = lim.cur;
|
||||
}
|
||||
if (min + 1 >= max) break;
|
||||
}
|
||||
}
|
||||
|
||||
test "fds" {
|
||||
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
||||
}
|
||||
|
||||
const usage_ast_check =
|
||||
\\Usage: zig ast-check [file]
|
||||
\\
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue