]> Cypherpunks repositories - gostls13.git/commitdiff
net: merge FreeBSD and DragonFly sendfile support
authorIan Lance Taylor <iant@golang.org>
Wed, 8 Feb 2017 23:03:56 +0000 (15:03 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 8 Feb 2017 23:15:14 +0000 (23:15 +0000)
The two files were identical except for comments.

Change-Id: Ifc300026c8e4584afa50a7b669099eaff146ea5d
Reviewed-on: https://go-review.googlesource.com/36631
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/sendfile_bsd.go [moved from src/net/sendfile_dragonfly.go with 76% similarity]
src/net/sendfile_freebsd.go [deleted file]

similarity index 76%
rename from src/net/sendfile_dragonfly.go
rename to src/net/sendfile_bsd.go
index d4b825c37051c859e8a633870a08069e580db50c..67e80c9c6a7758838c662ce76f76b12ae481218d 100644 (file)
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build dragonfly freebsd
+
 package net
 
 import (
@@ -22,10 +24,11 @@ const maxSendfileSize int = 4 << 20
 //
 // if handled == false, sendFile performed no work.
 func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
-       // DragonFly uses 0 as the "until EOF" value. If you pass in more bytes than the
-       // file contains, it will loop back to the beginning ad nauseam until it's sent
-       // exactly the number of bytes told to. As such, we need to know exactly how many
-       // bytes to send.
+       // FreeBSD and DragonFly use 0 as the "until EOF" value.
+       // If you pass in more bytes than the file contains, it will
+       // loop back to the beginning ad nauseam until it's sent
+       // exactly the number of bytes told to. As such, we need to
+       // know exactly how many bytes to send.
        var remain int64 = 0
 
        lr, ok := r.(*io.LimitedReader)
@@ -49,10 +52,11 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
                remain = fi.Size()
        }
 
-       // The other quirk with DragonFly's sendfile implementation is that it doesn't
-       // use the current position of the file -- if you pass it offset 0, it starts
-       // from offset 0. There's no way to tell it "start from current position", so
-       // we have to manage that explicitly.
+       // The other quirk with FreeBSD/DragonFly's sendfile
+       // implementation is that it doesn't use the current position
+       // of the file -- if you pass it offset 0, it starts from
+       // offset 0. There's no way to tell it "start from current
+       // position", so we have to manage that explicitly.
        pos, err := f.Seek(0, io.SeekCurrent)
        if err != nil {
                return 0, err, false
diff --git a/src/net/sendfile_freebsd.go b/src/net/sendfile_freebsd.go
deleted file mode 100644 (file)
index 18cbb27..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2011 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 (
-       "io"
-       "os"
-       "syscall"
-)
-
-// maxSendfileSize is the largest chunk size we ask the kernel to copy
-// at a time.
-const maxSendfileSize int = 4 << 20
-
-// sendFile copies the contents of r to c using the sendfile
-// system call to minimize copies.
-//
-// if handled == true, sendFile returns the number of bytes copied and any
-// non-EOF error.
-//
-// if handled == false, sendFile performed no work.
-func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
-       // FreeBSD uses 0 as the "until EOF" value. If you pass in more bytes than the
-       // file contains, it will loop back to the beginning ad nauseam until it's sent
-       // exactly the number of bytes told to. As such, we need to know exactly how many
-       // bytes to send.
-       var remain int64 = 0
-
-       lr, ok := r.(*io.LimitedReader)
-       if ok {
-               remain, r = lr.N, lr.R
-               if remain <= 0 {
-                       return 0, nil, true
-               }
-       }
-       f, ok := r.(*os.File)
-       if !ok {
-               return 0, nil, false
-       }
-
-       if remain == 0 {
-               fi, err := f.Stat()
-               if err != nil {
-                       return 0, err, false
-               }
-
-               remain = fi.Size()
-       }
-
-       // The other quirk with FreeBSD's sendfile implementation is that it doesn't
-       // use the current position of the file -- if you pass it offset 0, it starts
-       // from offset 0. There's no way to tell it "start from current position", so
-       // we have to manage that explicitly.
-       pos, err := f.Seek(0, io.SeekCurrent)
-       if err != nil {
-               return 0, err, false
-       }
-
-       if err := c.writeLock(); err != nil {
-               return 0, err, true
-       }
-       defer c.writeUnlock()
-
-       dst := c.sysfd
-       src := int(f.Fd())
-       for remain > 0 {
-               n := maxSendfileSize
-               if int64(n) > remain {
-                       n = int(remain)
-               }
-               pos1 := pos
-               n, err1 := syscall.Sendfile(dst, src, &pos1, n)
-               if n > 0 {
-                       pos += int64(n)
-                       written += int64(n)
-                       remain -= int64(n)
-               }
-               if n == 0 && err1 == nil {
-                       break
-               }
-               if err1 == syscall.EAGAIN {
-                       if err1 = c.pd.waitWrite(); err1 == nil {
-                               continue
-                       }
-               }
-               if err1 == syscall.EINTR {
-                       continue
-               }
-               if err1 != nil {
-                       // This includes syscall.ENOSYS (no kernel
-                       // support) and syscall.EINVAL (fd types which
-                       // don't implement sendfile)
-                       err = err1
-                       break
-               }
-       }
-       if lr != nil {
-               lr.N = remain
-       }
-       if err != nil {
-               err = os.NewSyscallError("sendfile", err)
-       }
-       return written, err, written > 0
-}