| ... | @@ -2982,35 +2982,37 @@ fn parseCodeModel(arg: []const u8) std.builtin.CodeModel { | ... | @@ -2982,35 +2982,37 @@ fn parseCodeModel(arg: []const u8) std.builtin.CodeModel { |
| 2982 | /// garbage collector to run concurrently to zig processes, and to allow multiple | 2982 | /// garbage collector to run concurrently to zig processes, and to allow multiple |
| 2983 | /// zig processes to run concurrently with each other, without clobbering each other. | 2983 | /// zig processes to run concurrently with each other, without clobbering each other. |
| 2984 | fn gimmeMoreOfThoseSweetSweetFileDescriptors() void { | 2984 | fn gimmeMoreOfThoseSweetSweetFileDescriptors() void { |
| 2985 | switch (std.Target.current.os.tag) { | 2985 | if (!@hasDecl(std.os, "rlimit")) return; |
| 2986 | .windows, .wasi, .uefi, .other, .freestanding => return, | | |
| 2987 | // std lib is missing getrlimit/setrlimit. | | |
| 2988 | // https://github.com/ziglang/zig/issues/6361 | | |
| 2989 | //else => {}, | | |
| 2990 | else => return, | | |
| 2991 | } | | |
| 2992 | const posix = std.os; | 2986 | const posix = std.os; |
| 2993 | var lim = posix.getrlimit(posix.RLIMIT_NOFILE, &lim) catch return; // Oh well; we tried. | 2987 | |
| | 2988 | var lim = posix.getrlimit(.NOFILE) catch return; // Oh well; we tried. |
| | 2989 | if (comptime std.Target.current.isDarwin()) { |
| | 2990 | // On Darwin, `NOFILE` is bounded by a hardcoded value `OPEN_MAX`. |
| | 2991 | // According to the man pages for setrlimit(): |
| | 2992 | // setrlimit() now returns with errno set to EINVAL in places that historically succeeded. |
| | 2993 | // It no longer accepts "rlim_cur = RLIM_INFINITY" for RLIM_NOFILE. |
| | 2994 | // Use "rlim_cur = min(OPEN_MAX, rlim_max)". |
| | 2995 | lim.max = std.math.min(std.os.darwin.OPEN_MAX, lim.max); |
| | 2996 | } |
| 2994 | if (lim.cur == lim.max) return; | 2997 | if (lim.cur == lim.max) return; |
| | 2998 | |
| | 2999 | // Do a binary search for the limit. |
| | 3000 | var min: posix.rlim_t = lim.cur; |
| | 3001 | var max: posix.rlim_t = 1 << 20; |
| | 3002 | // But if there's a defined upper bound, don't search, just set it. |
| | 3003 | if (lim.max != posix.RLIM_INFINITY) { |
| | 3004 | min = lim.max; |
| | 3005 | max = lim.max; |
| | 3006 | } |
| | 3007 | |
| 2995 | while (true) { | 3008 | while (true) { |
| 2996 | // Do a binary search for the limit. | 3009 | lim.cur = min + @divTrunc(max - min, 2); // on freebsd rlim_t is signed |
| 2997 | var min: posix.rlim_t = lim.cur; | 3010 | if (posix.setrlimit(.NOFILE, lim)) |_| { |
| 2998 | var max: posix.rlim_t = 1 << 20; | 3011 | min = lim.cur; |
| 2999 | // But if there's a defined upper bound, don't search, just set it. | 3012 | } else |_| { |
| 3000 | if (lim.max != posix.RLIM_INFINITY) { | 3013 | max = lim.cur; |
| 3001 | min = lim.max; | | |
| 3002 | max = lim.max; | | |
| 3003 | } | | |
| 3004 | while (true) { | | |
| 3005 | lim.cur = min + (max - min) / 2; | | |
| 3006 | if (posix.setrlimit(posix.RLIMIT_NOFILE, lim)) |_| { | | |
| 3007 | min = lim.cur; | | |
| 3008 | } else |_| { | | |
| 3009 | max = lim.cur; | | |
| 3010 | } | | |
| 3011 | if (min + 1 < max) continue; | | |
| 3012 | return; | | |
| 3013 | } | 3014 | } |
| | 3015 | if (min + 1 >= max) break; |
| 3014 | } | 3016 | } |
| 3015 | } | 3017 | } |
| 3016 | | 3018 | |