net: refactor poller into new internal/poll package

This will make it possible to use the poller with the os package.

This is a lot of code movement but the behavior is intended to be
unchanged.

Update #6817.
Update #7903.
Update #15021.
Update #18507.

Change-Id: I1413685928017c32df5654ded73a2643820977ae
Reviewed-on: https://go-review.googlesource.com/36799
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/src/net/sendfile_bsd.go b/src/net/sendfile_bsd.go
index 67e80c9..7a2b48c 100644
--- a/src/net/sendfile_bsd.go
+++ b/src/net/sendfile_bsd.go
@@ -7,15 +7,11 @@
 package net
 
 import (
+	"internal/poll"
 	"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.
 //
@@ -62,49 +58,10 @@
 		return 0, err, false
 	}
 
-	if err := c.writeLock(); err != nil {
-		return 0, err, true
-	}
-	defer c.writeUnlock()
+	written, err = poll.SendFile(&c.pfd, int(f.Fd()), pos, remain)
 
-	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
+		lr.N = remain - written
 	}
-	if err != nil {
-		err = os.NewSyscallError("sendfile", err)
-	}
-	return written, err, written > 0
+	return written, wrapSyscallError("sendfile", err), written > 0
 }