diff options
| author | Junio C Hamano <gitster@pobox.com> | 2026-03-24 12:31:34 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2026-03-24 12:31:34 -0700 |
| commit | 8023abc632ea45a9a1b7f78b13db2cf541849775 (patch) | |
| tree | b06aa8b5ec54b28bd580d80dbee0afe14b9149bc /wrapper.c | |
| parent | 231f8100c41fdbdd49f5bca953fff775a79321db (diff) | |
| parent | 835e0aaf6f0e07e9f9a393ed0e456db7c1be33ef (diff) | |
| download | git-8023abc632ea45a9a1b7f78b13db2cf541849775.tar.xz | |
Merge branch 'ps/upload-pack-buffer-more-writes'
Reduce system overhead "git upload-pack" spends on relaying "git
pack-objects" output to the "git fetch" running on the other end of
the connection.
* ps/upload-pack-buffer-more-writes:
builtin/pack-objects: reduce lock contention when writing packfile data
csum-file: drop `hashfd_throughput()`
csum-file: introduce `hashfd_ext()`
sideband: use writev(3p) to send pktlines
wrapper: introduce writev(3p) wrappers
compat/posix: introduce writev(3p) wrapper
upload-pack: reduce lock contention when writing packfile data
upload-pack: prefer flushing data over sending keepalive
upload-pack: adapt keepalives based on buffering
upload-pack: fix debug statement when flushing packfile data
Diffstat (limited to 'wrapper.c')
| -rw-r--r-- | wrapper.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -323,6 +323,47 @@ ssize_t write_in_full(int fd, const void *buf, size_t count) return total; } +ssize_t writev_in_full(int fd, struct iovec *iov, int iovcnt) +{ + ssize_t total_written = 0; + + while (iovcnt) { + ssize_t bytes_written = writev(fd, iov, iovcnt); + if (bytes_written < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!bytes_written) { + errno = ENOSPC; + return -1; + } + + total_written += bytes_written; + + /* + * We first need to discard any iovec entities that have been + * fully written. + */ + while (iovcnt && (size_t)bytes_written >= iov->iov_len) { + bytes_written -= iov->iov_len; + iov++; + iovcnt--; + } + + /* + * Finally, we need to adjust the last iovec in case we have + * performed a partial write. + */ + if (iovcnt && bytes_written) { + iov->iov_base = (char *) iov->iov_base + bytes_written; + iov->iov_len -= bytes_written; + } + } + + return total_written; +} + ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset) { char *p = buf; |
