summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmadeusz Sławiński <amade@asmblr.net>2019-11-02 23:21:54 +0100
committerAmadeusz Sławiński <amade@asmblr.net>2019-12-28 13:41:04 +0100
commit3e37405972d49eb3d81301167693bcea1b2c3d71 (patch)
treec4f0bcd5c95c58dbf59badc5007b4720894e9f97
parentf66377f9927bf5a1857b1106b28008f3802e1f7b (diff)
downloadscreen-3e37405972d49eb3d81301167693bcea1b2c3d71.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.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/misc.c b/src/misc.c
index 643ade0..2690923 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -30,6 +30,7 @@
#include "misc.h"
+#include <poll.h>
#include <sys/types.h>
#include <sys/stat.h> /* mkdir() declaration */
#include <signal.h>
@@ -151,11 +152,30 @@ void Kill(pid_t pid, int sig)
void closeallfiles(int except)
{
- int f;
- f = getdtablesize();
- while (--f > 2)
- if (f != except)
- close(f);
+ struct pollfd pfd[1024];
+ int maxfd, i, fd, ret, z;
+
+ i = 3; /* skip stdin, stdout and stderr */
+ maxfd = getdtablesize();
+
+ while (i < maxfd) {
+ memset(pfd, 0, sizeof(pfd));
+
+ z = 0;
+ for (fd = i; fd < maxfd && fd < i + 1024; fd++)
+ pfd[z++].fd = fd;
+
+ ret = poll(pfd, fd - i, 0);
+ if (ret < 0)
+ Panic(errno, "poll");
+
+ z = 0;
+ for (fd = i; fd < maxfd && fd < i + 1024; fd++)
+ if (!(pfd[z++].revents & POLLNVAL) && fd != except)
+ close(fd);
+
+ i = fd;
+ }
}
/*