summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2021-04-13 16:24:45 +0200
committerGitHub <noreply@github.com>2021-04-13 10:24:45 -0400
commitd46b37f6a8639e25ff54ea1e264cc7cebdd03be9 (patch)
treea6db53645ea981501acc1a977e40762beb45796c
parentdf49a8462caf1cf4eea5c9f386322dae5e14dc4f (diff)
feat(cli): raise file descriptor limit on startup (#10162)
Raise the soft limit to the hard limit when possible. This is similar to what Node.js does to avoid running into "out of file descriptors" errors too quickly. On most Linux systems, raises the limit from 1,024 to 1,048,576. On most macOS systems, raises the limit from 256 to 10,240. Fixes #10148.
-rw-r--r--cli/main.rs2
-rw-r--r--cli/main_runtime.rs2
-rw-r--r--cli/unix_util.rs41
3 files changed, 45 insertions, 0 deletions
diff --git a/cli/main.rs b/cli/main.rs
index d8e893906..0005bb891 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -36,6 +36,7 @@ mod tokio_util;
mod tools;
mod tsc;
mod tsc_config;
+mod unix_util;
mod version;
use crate::file_fetcher::File;
@@ -1176,6 +1177,7 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
pub fn main() {
#[cfg(windows)]
colors::enable_ansi(); // For Windows 10
+ unix_util::raise_fd_limit();
let args: Vec<String> = env::args().collect();
let standalone_res = match standalone::extract_standalone(args.clone()) {
diff --git a/cli/main_runtime.rs b/cli/main_runtime.rs
index db3f9fd02..23f1c23b6 100644
--- a/cli/main_runtime.rs
+++ b/cli/main_runtime.rs
@@ -5,6 +5,7 @@
mod colors;
mod standalone;
mod tokio_util;
+mod unix_util;
mod version;
use deno_core::error::anyhow;
@@ -14,6 +15,7 @@ use std::env;
pub fn main() {
#[cfg(windows)]
colors::enable_ansi(); // For Windows 10
+ unix_util::raise_fd_limit();
let args: Vec<String> = env::args().collect();
if let Err(err) = run(args) {
diff --git a/cli/unix_util.rs b/cli/unix_util.rs
new file mode 100644
index 000000000..4aa8ef55d
--- /dev/null
+++ b/cli/unix_util.rs
@@ -0,0 +1,41 @@
+/// Raise soft file descriptor limit to hard file descriptor limit.
+/// This is the difference between `ulimit -n` and `ulimit -n -H`.
+pub fn raise_fd_limit() {
+ #[cfg(unix)]
+ unsafe {
+ let mut limits = libc::rlimit {
+ rlim_cur: 0,
+ rlim_max: 0,
+ };
+
+ if 0 != libc::getrlimit(libc::RLIMIT_NOFILE, &mut limits) {
+ return;
+ }
+
+ if limits.rlim_cur == libc::RLIM_INFINITY {
+ return;
+ }
+
+ // No hard limit? Do a binary search for the effective soft limit.
+ if limits.rlim_max == libc::RLIM_INFINITY {
+ let mut min = limits.rlim_cur;
+ let mut max = 1 << 20;
+
+ while min + 1 < max {
+ limits.rlim_cur = min + (max - min) / 2;
+ match libc::setrlimit(libc::RLIMIT_NOFILE, &limits) {
+ 0 => min = limits.rlim_cur,
+ _ => max = limits.rlim_cur,
+ }
+ }
+
+ return;
+ }
+
+ // Raise the soft limit to the hard limit.
+ if limits.rlim_cur < limits.rlim_max {
+ limits.rlim_cur = limits.rlim_max;
+ libc::setrlimit(libc::RLIMIT_NOFILE, &limits);
+ }
+ }
+}