fd8131a35e
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
58 lines
1.7 KiB
Diff
58 lines
1.7 KiB
Diff
From: John Eckersberg <jeckersb@redhat.com>
|
|
Date: Fri, 11 Oct 2019 13:06:20 -0400
|
|
Subject: [PATCH] erl_child_setup: reduce number of calls to close()
|
|
|
|
On systems without closefrom(), such as Linux, iterating over all
|
|
possible file descriptors and calling close() for each is inefficient.
|
|
This is markedly so when the maximum number of file descriptors has
|
|
been tuned to a large number.
|
|
|
|
Instead, walk the open descriptors under /dev/fd and close only those
|
|
which are open.
|
|
|
|
diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c
|
|
index 129861ebd5..7ddd753136 100644
|
|
--- a/erts/emulator/sys/unix/erl_child_setup.c
|
|
+++ b/erts/emulator/sys/unix/erl_child_setup.c
|
|
@@ -411,6 +411,7 @@ main(int argc, char *argv[])
|
|
int uds_fd = 3, max_fd = 3;
|
|
#ifndef HAVE_CLOSEFROM
|
|
int i;
|
|
+ DIR *dir;
|
|
#endif
|
|
struct sigaction sa;
|
|
|
|
@@ -426,11 +427,29 @@ main(int argc, char *argv[])
|
|
#if defined(HAVE_CLOSEFROM)
|
|
closefrom(4);
|
|
#else
|
|
- for (i = 4; i < max_files; i++)
|
|
+ dir = opendir("/dev/fd");
|
|
+ if (dir == NULL) { /* /dev/fd not available */
|
|
+ for (i = 4; i < max_files; i++)
|
|
#if defined(__ANDROID__)
|
|
- if (i != system_properties_fd())
|
|
+ if (i != system_properties_fd())
|
|
#endif
|
|
- (void) close(i);
|
|
+ (void) close(i);
|
|
+ } else {
|
|
+ /* Iterate over fds obtained from /dev/fd */
|
|
+ struct dirent *entry;
|
|
+ int dir_fd = dirfd(dir);
|
|
+
|
|
+ while ((entry = readdir(dir)) != NULL) {
|
|
+ i = atoi(entry->d_name);
|
|
+#if defined(__ANDROID__)
|
|
+ if (i != system_properties_fd())
|
|
+#endif
|
|
+ if (i >= 4 && i != dir_fd)
|
|
+ (void) close(i);
|
|
+ }
|
|
+
|
|
+ closedir(dir);
|
|
+ }
|
|
#endif
|
|
|
|
if (pipe(sigchld_pipe) < 0) {
|