From c1c4f74fc92219099af1ec419f543f961bea0720 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Sun, 22 Apr 2018 10:33:49 +1200 Subject: [PATCH] Track open fds in vector not set The lowest unused fd is used whenever a new fd is needed so we can expect them to form a dense set and vector should be an efficient representation both in space and time. --- xapian-core/tests/harness/fdtracker.cc | 30 ++++++++++++++++++++++++------ xapian-core/tests/harness/fdtracker.h | 14 ++++++++++++-- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/xapian-core/tests/harness/fdtracker.cc b/xapian-core/tests/harness/fdtracker.cc index 22615117d..7fe08e038 100644 --- a/xapian-core/tests/harness/fdtracker.cc +++ b/xapian-core/tests/harness/fdtracker.cc @@ -49,6 +49,22 @@ using namespace std; # define FD_DIRECTORY "/dev/fd" #endif +void +FDTracker::mark_fd(int fd) +{ + if (fd >= 0) { + if (size_t(fd) >= fds.size()) + fds.resize((fd &~ 31) + 32); + fds[fd] = true; + } +} + +bool +FDTracker::check_fd(int fd) const +{ + return size_t(fd) < fds.size() && fds[fd]; +} + FDTracker::~FDTracker() { if (dir_void) { @@ -84,8 +100,7 @@ FDTracker::init() if (name[0] < '0' || name[0] > '9') continue; - int fd = atoi(name); - fds.insert(fd); + mark_fd(atoi(name)); } } @@ -116,7 +131,10 @@ FDTracker::check() continue; int fd = atoi(name); - if (fds.find(fd) != fds.end()) continue; + if (check_fd(fd)) { + // This fd was already open before the testcase. + continue; + } string proc_symlink = FD_DIRECTORY "/"; proc_symlink += name; @@ -129,7 +147,7 @@ FDTracker::check() memcmp(buf, "/dev/urandom", CONST_STRLEN("/dev/urandom")) == 0) { // /dev/urandom isn't a real leak - something in the C library // opens it lazily (at least on Linux). - fds.insert(fd); + mark_fd(fd); continue; } @@ -140,8 +158,8 @@ FDTracker::check() message.append(buf, res); } - // Insert the leaked fd so we don't report it for future tests. - fds.insert(fd); + // Mark the leaked fd as used so we don't report it for future tests. + mark_fd(fd); ok = false; } return ok; diff --git a/xapian-core/tests/harness/fdtracker.h b/xapian-core/tests/harness/fdtracker.h index bc8bd4639..32696b7ee 100644 --- a/xapian-core/tests/harness/fdtracker.h +++ b/xapian-core/tests/harness/fdtracker.h @@ -21,8 +21,8 @@ #ifndef XAPIAN_INCLUDED_FDTRACKER_H #define XAPIAN_INCLUDED_FDTRACKER_H -#include #include +#include // Disable fd tracking where it can't possibly work. #ifndef __WIN32__ @@ -31,7 +31,13 @@ class FDTracker { #ifdef XAPIAN_TESTSUITE_TRACK_FDS - std::set fds; + /** Which fds are open. + * + * The lowest unused fd is used whenever a new fd is needed so we + * can expect them to form a dense set and vector should be an + * efficient representation both in space and time. + */ + std::vector fds; /** The DIR* from opendir("/proc/self/fd") (or equivalent) cast to void*. * @@ -42,6 +48,10 @@ class FDTracker { std::string message; + void mark_fd(int fd); + + bool check_fd(int fd) const; + public: FDTracker() : dir_void(NULL) { } -- 2.11.4.GIT