From c03de0df627864fb7e83e9af88201b8a5fcd4930 Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Fri, 29 Mar 2024 20:29:44 -0400 Subject: gc: Find roots using libproc on Darwin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the garbage collector found runtime roots on Darwin by shelling out to `lsof -n -w -F n` then parsing the result. However, this requires an lsof binary and can be extremely slow. The official Apple lsof returns in a reasonable amount of time, about 250ms in my tests, but the lsof packaged in nixpkgs is quite slow, taking about 40 seconds to run the command. Using libproc directly is about the same speed as Apple lsof, and allows us to reënable several tests that were disabled on Darwin. Change-Id: Ifa0adda7984e13c15535693baba835aae79a3577 --- src/libstore/platform/linux.cc | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/libstore/platform/linux.cc') diff --git a/src/libstore/platform/linux.cc b/src/libstore/platform/linux.cc index 9be3e47da..a34608894 100644 --- a/src/libstore/platform/linux.cc +++ b/src/libstore/platform/linux.cc @@ -1,6 +1,7 @@ #include "gc-store.hh" #include "signals.hh" #include "platform/linux.hh" +#include "regex.hh" #include @@ -26,12 +27,6 @@ static void readProcLink(const std::string & file, UncheckedRoots & roots) } } -static std::string quoteRegexChars(const std::string & raw) -{ - static auto specialRegex = std::regex(R"([.^$\\*+?()\[\]{}|])"); - return std::regex_replace(raw, specialRegex, R"(\$&)"); -} - static void readFileRoots(const char * path, UncheckedRoots & roots) { try { @@ -50,8 +45,7 @@ void LinuxLocalStore::findPlatformRoots(UncheckedRoots & unchecked) struct dirent * ent; auto digitsRegex = std::regex(R"(^\d+$)"); auto mapRegex = std::regex(R"(^\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(/\S+)\s*$)"); - auto storePathRegex = - std::regex(quoteRegexChars(storeDir) + R"(/[0-9a-z]+[0-9a-zA-Z\+\-\._\?=]*)"); + auto storePathRegex = regex::storePathRegex(storeDir); while (errno = 0, ent = readdir(procDir.get())) { checkInterrupt(); if (std::regex_match(ent->d_name, digitsRegex)) { -- cgit v1.2.3