summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmadeusz Sławiński <amade@asmblr.net>2019-11-02 23:21:40 +0100
committerAmadeusz Sławiński <amade@asmblr.net>2019-12-28 13:41:29 +0100
commit09bbd3eff39817a1ee8bb0d56393b156aa86eb05 (patch)
tree477719cc256f07d3741fccb401a817aa08a957a7
parentb7a76150844fcca9f8680e61ec2a358b019eec46 (diff)
downloadscreen-09bbd3eff39817a1ee8bb0d56393b156aa86eb05.tar.gz
Make closeallfiles() faster
Optimize startup time, making closeallfiles() faster, by doing less system calls. Instead of calling close for each possible file, use poll() to check if file exist at all. On linux with open file limit set to 1048576, it should do 1024 poll() calls instead of 1048576 close(). Bug: 55618 Signed-off-by: Amadeusz Sławiński <amade@asmblr.net>
-rw-r--r--src/misc.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/misc.c b/src/misc.c
index 9758693..2022a06 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -26,6 +26,7 @@
****************************************************************
*/
+#include <poll.h>
#include <sys/types.h>
#include <sys/stat.h> /* mkdir() declaration */
#include <signal.h>
@@ -379,12 +380,38 @@ int except;
#endif /* SVR4 */
#if defined(SYSV) && defined(NOFILE) && !defined(ISC)
f = NOFILE;
-#else /* SYSV && !ISC */
- f = getdtablesize();
-#endif /* SYSV && !ISC */
while (--f > 2)
if (f != except)
close(f);
+#else /* SYSV && !ISC */
+ {
+ struct pollfd pfd[1024];
+ int maxfd, i, ret, z;
+
+ i = 3; /* skip stdin, stdout and stderr */
+ maxfd = getdtablesize();
+
+ while (i < maxfd)
+ {
+ memset(pfd, 0, sizeof(pfd));
+
+ z = 0;
+ for (f = i; f < maxfd && f < i + 1024; f++)
+ pfd[z++].fd = f;
+
+ ret = poll(pfd, f - i, 0);
+ if (ret < 0)
+ Panic(errno, "poll");
+
+ z = 0;
+ for (f = i; f < maxfd && f < i + 1024; f++)
+ if (!(pfd[z++].revents & POLLNVAL) && f != except)
+ close(f);
+
+ i = f;
+ }
+ }
+#endif /* SYSV && !ISC */
}
#endif /* HAVE_FDWALK */