diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2011-12-15T12·32+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2011-12-15T12·32+0000 |
commit | a3e0656cbbfadba28518e0a29c324edaabb9874a (patch) | |
tree | 026d7097aed0755d3de2eca9e500b504f20b7410 /src/libutil/serialise.cc | |
parent | 3a48282b0681d68147e18f7464eaddf1d188c3be (diff) |
* Buffer reads in FdSource. Together with write buffering, this
significantly cuts down the number of syscalls (e.g., for "nix-store -qR /var/run/current-system" via the daemon, it reduced the number of syscalls in the client from 29134 to 4766 and in the daemon from 44266 to 20666).
Diffstat (limited to 'src/libutil/serialise.cc')
-rw-r--r-- | src/libutil/serialise.cc | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 66a64a6be4c8..e3a53c0d01dc 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -2,6 +2,7 @@ #include "util.hh" #include <cstring> +#include <cerrno> namespace nix { @@ -38,7 +39,28 @@ void FdSink::flush() void FdSource::operator () (unsigned char * data, unsigned int len) { - readFull(fd, data, len); + if (!buffer) buffer = new unsigned char[bufSize]; + + while (len) { + if (!bufPosIn) { + /* Read as much data as is available (up to the buffer + size). */ + checkInterrupt(); + ssize_t n = read(fd, (char *) buffer, bufSize); + if (n == -1) { + if (errno == EINTR) continue; + throw SysError("reading from file"); + } + if (n == 0) throw EndOfFile("unexpected end-of-file"); + bufPosIn = n; + } + + /* Copy out the data in the buffer. */ + size_t n = len > bufPosIn - bufPosOut ? bufPosIn - bufPosOut : len; + memcpy(data, buffer + bufPosOut, n); + data += n; bufPosOut += n; len -= n; + if (bufPosIn == bufPosOut) bufPosIn = bufPosOut = 0; + } } |