1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 04:21:16 +02:00

withFramedSink(): Don't use a thread to monitor the other side

Since withFramedSink() is now used a lot more than in the past (for
every addToStore() variant), we were creating a lot of threads, e.g.

  nix flake show --no-eval-cache --all-systems github:NixOS/nix/afdd12be5e19c0001ff3297dea544301108d298

would create 46418 threads. While threads on Linux are cheap, this is
still substantial overhead.

So instead, just poll from FramedSink before every write whether there
are pending messages from the daemon. This could slightly increase the
latency on log messages from the daemon, but not on exceptions (which
were only synchronously checked from FramedSink anyway).

This speeds up the command above from 19.2s to 17.5s on my machine (a
9% speedup).

(cherry picked from commit 39daa4a0d3)
This commit is contained in:
Eelco Dolstra 2024-08-19 17:49:26 +02:00 committed by Mergify
parent e0c8b0fc4f
commit 36f3fb72e9
6 changed files with 61 additions and 52 deletions

View file

@ -10,6 +10,8 @@
#ifdef _WIN32
# include <fileapi.h>
# include "windows-error.hh"
#else
# include <poll.h>
#endif
@ -158,6 +160,24 @@ bool FdSource::good()
}
bool FdSource::hasData()
{
if (BufferedSource::hasData()) return true;
while (true) {
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
auto n = poll(fds, 1, 0);
if (n < 0) {
if (errno == EINTR) continue;
throw SysError("polling file descriptor");
}
return n == 1 && (fds[0].events & POLLIN);
}
}
size_t StringSource::read(char * data, size_t len)
{
if (pos == s.size()) throw EndOfFile("end of string reached");