Skip to content

net.sendFile does not use sendfile() on linux in all the cases in which it is available #7005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gopherbot opened this issue Dec 22, 2013 · 2 comments

Comments

@gopherbot
Copy link
Contributor

by shawnlandden:

sendfile() is backed by splice() which can do arbitrary bidirectional IO between a
limited set of fd types, including TCP UDP files AF_ALG, etc (anything with a sendpage()
handler in the kernel)

the following application connects two tcp sockets, which sendfile() supports, but the
go runtime does not use sendfile()

this patch doesn't work, and i'm not sure why, i'm being held up by 6776

diff -r c4b7c0824984 src/pkg/net/sendfile_linux.go
--- a/src/pkg/net/sendfile_linux.go Fri Dec 20 23:19:32 2013 -0800
+++ b/src/pkg/net/sendfile_linux.go Sun Dec 22 15:42:18 2013 -0800
@@ -8,6 +8,8 @@
    "io"
    "os"
    "syscall"
+   "reflect"
+   "fmt"
 )
 
 // maxSendfileSize is the largest chunk size we ask the kernel to copy
@@ -31,9 +33,17 @@
            return 0, nil, true
        }
    }
+   fmt.Println(reflect.TypeOf(r))
    f, ok := r.(*os.File)
+   var src int
    if !ok {
-       return 0, nil, false
+       t, ok := r.(*TCPConn)
+       if !ok {
+           return 0, nil, false
+       }
+       src = t.conn.fd.sysfd
+   } else {
+       src = int(f.Fd())
    }
 
    if err := c.writeLock(); err != nil {
@@ -42,7 +52,6 @@
    defer c.writeUnlock()
 
    dst := c.sysfd
-   src := int(f.Fd())
    for remain > 0 {
        n := maxSendfileSize
        if int64(n) > remain {

What steps will reproduce the problem?
If possible, include a link to a program on play.golang.org.
1.run http://play.golang.org/p/EvOJBw-Esm in strace
2. uses read/write when sendfile() possible


Which compiler are you using (5g, 6g, 8g, gccgo)?
6g. gccgo create a program that crashes (debian sid)

Which operating system are you using?
debian sid

Which version are you using?  (run 'go version')
go version go1.2 linux/amd64

Please provide any additional information below.
@bradfitz
Copy link
Contributor

Comment 1:

I don't think we need to support every possibility here.  Historically Linux didn't
support socket->socket sendfile/splice.  That came later.  Go supports the minimum to be
able to serve static files efficiently.  Any use of more modern kernel features would
have to fall back gracefully if the kernel didn't support it.
Also, we don't use the bug tracker for sending or discussing patches.  See the
contributing docs for how to use the hg plugins.

@rsc
Copy link
Contributor

rsc commented Mar 3, 2014

Comment 2:

Status changed to WorkingAsIntended.

@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants