diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /src/net/splice_linux.go | |
parent | Initial commit. (diff) | |
download | golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.tar.xz golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/net/splice_linux.go')
-rw-r--r-- | src/net/splice_linux.go | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/net/splice_linux.go b/src/net/splice_linux.go new file mode 100644 index 0000000..69c3f65 --- /dev/null +++ b/src/net/splice_linux.go @@ -0,0 +1,44 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +import ( + "internal/poll" + "io" +) + +// splice transfers data from r to c using the splice system call to minimize +// copies from and to userspace. c must be a TCP connection. Currently, splice +// is only enabled if r is a TCP or a stream-oriented Unix connection. +// +// If splice returns handled == false, it has performed no work. +func splice(c *netFD, r io.Reader) (written int64, err error, handled bool) { + var remain int64 = 1 << 62 // by default, copy until EOF + lr, ok := r.(*io.LimitedReader) + if ok { + remain, r = lr.N, lr.R + if remain <= 0 { + return 0, nil, true + } + } + + var s *netFD + if tc, ok := r.(*TCPConn); ok { + s = tc.fd + } else if uc, ok := r.(*UnixConn); ok { + if uc.fd.net != "unix" { + return 0, nil, false + } + s = uc.fd + } else { + return 0, nil, false + } + + written, handled, sc, err := poll.Splice(&c.pfd, &s.pfd, remain) + if lr != nil { + lr.N -= written + } + return written, wrapSyscallError(sc, err), handled +} |