mirror of
https://github.com/golang/go
synced 2024-11-25 07:07:57 -07:00
net: Sendfile for win32.
implement using TransmitFile(). R=bsiegert, bradfitz, alex.brainman, rsc, go.peter.90 CC=golang-dev https://golang.org/cl/4536076
This commit is contained in:
parent
968afa0e8c
commit
1374097381
@ -82,7 +82,7 @@ GOFILES_windows=\
|
|||||||
file_windows.go\
|
file_windows.go\
|
||||||
interface_stub.go\
|
interface_stub.go\
|
||||||
resolv_windows.go\
|
resolv_windows.go\
|
||||||
sendfile_stub.go\
|
sendfile_windows.go\
|
||||||
sock_windows.go\
|
sock_windows.go\
|
||||||
|
|
||||||
GOFILES+=$(GOFILES_$(GOOS))
|
GOFILES+=$(GOFILES_$(GOOS))
|
||||||
|
68
src/pkg/net/sendfile_windows.go
Normal file
68
src/pkg/net/sendfile_windows.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
type sendfileOp struct {
|
||||||
|
anOp
|
||||||
|
src int32 // source
|
||||||
|
n uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *sendfileOp) Submit() (errno int) {
|
||||||
|
return syscall.TransmitFile(int32(o.fd.sysfd), o.src, o.n, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *sendfileOp) Name() string {
|
||||||
|
return "TransmitFile"
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendFile copies the contents of r to c using the TransmitFile
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// Note that sendfile for windows does not suppport >2GB file.
|
||||||
|
func sendFile(c *netFD, r io.Reader) (written int64, err os.Error, handled bool) {
|
||||||
|
var n int64 = 0 // by default, copy until EOF
|
||||||
|
|
||||||
|
lr, ok := r.(*io.LimitedReader)
|
||||||
|
if ok {
|
||||||
|
n, r = lr.N, lr.R
|
||||||
|
if n <= 0 {
|
||||||
|
return 0, nil, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f, ok := r.(*os.File)
|
||||||
|
if !ok {
|
||||||
|
return 0, nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
c.wio.Lock()
|
||||||
|
defer c.wio.Unlock()
|
||||||
|
c.incref()
|
||||||
|
defer c.decref()
|
||||||
|
|
||||||
|
var o sendfileOp
|
||||||
|
o.Init(c)
|
||||||
|
o.n = uint32(n)
|
||||||
|
o.src = int32(f.Fd())
|
||||||
|
done, err := iosrv.ExecIO(&o, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err, false
|
||||||
|
}
|
||||||
|
if lr != nil {
|
||||||
|
lr.N -= int64(done)
|
||||||
|
}
|
||||||
|
return int64(done), nil, true
|
||||||
|
}
|
@ -173,6 +173,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, errno
|
|||||||
//sys FlushViewOfFile(addr uintptr, length uintptr) (errno int)
|
//sys FlushViewOfFile(addr uintptr, length uintptr) (errno int)
|
||||||
//sys VirtualLock(addr uintptr, length uintptr) (errno int)
|
//sys VirtualLock(addr uintptr, length uintptr) (errno int)
|
||||||
//sys VirtualUnlock(addr uintptr, length uintptr) (errno int)
|
//sys VirtualUnlock(addr uintptr, length uintptr) (errno int)
|
||||||
|
//sys TransmitFile(s int32, handle int32, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (errno int) = wsock32.TransmitFile
|
||||||
|
|
||||||
// syscall interface implementation for other packages
|
// syscall interface implementation for other packages
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ var (
|
|||||||
procFlushViewOfFile = getSysProcAddr(modkernel32, "FlushViewOfFile")
|
procFlushViewOfFile = getSysProcAddr(modkernel32, "FlushViewOfFile")
|
||||||
procVirtualLock = getSysProcAddr(modkernel32, "VirtualLock")
|
procVirtualLock = getSysProcAddr(modkernel32, "VirtualLock")
|
||||||
procVirtualUnlock = getSysProcAddr(modkernel32, "VirtualUnlock")
|
procVirtualUnlock = getSysProcAddr(modkernel32, "VirtualUnlock")
|
||||||
|
procTransmitFile = getSysProcAddr(modwsock32, "TransmitFile")
|
||||||
procWSAStartup = getSysProcAddr(modwsock32, "WSAStartup")
|
procWSAStartup = getSysProcAddr(modwsock32, "WSAStartup")
|
||||||
procWSACleanup = getSysProcAddr(modwsock32, "WSACleanup")
|
procWSACleanup = getSysProcAddr(modwsock32, "WSACleanup")
|
||||||
procsocket = getSysProcAddr(modwsock32, "socket")
|
procsocket = getSysProcAddr(modwsock32, "socket")
|
||||||
@ -1008,6 +1009,20 @@ func VirtualUnlock(addr uintptr, length uintptr) (errno int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TransmitFile(s int32, handle int32, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (errno int) {
|
||||||
|
r1, _, e1 := Syscall9(procTransmitFile, 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
|
||||||
|
if int(r1) == 0 {
|
||||||
|
if e1 != 0 {
|
||||||
|
errno = int(e1)
|
||||||
|
} else {
|
||||||
|
errno = EINVAL
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errno = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func WSAStartup(verreq uint32, data *WSAData) (sockerrno int) {
|
func WSAStartup(verreq uint32, data *WSAData) (sockerrno int) {
|
||||||
r0, _, _ := Syscall(procWSAStartup, 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
|
r0, _, _ := Syscall(procWSAStartup, 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
|
||||||
sockerrno = int(r0)
|
sockerrno = int(r0)
|
||||||
|
@ -545,3 +545,19 @@ type DNSRecord struct {
|
|||||||
Reserved uint32
|
Reserved uint32
|
||||||
Data [40]byte
|
Data [40]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
TF_DISCONNECT = 1
|
||||||
|
TF_REUSE_SOCKET = 2
|
||||||
|
TF_WRITE_BEHIND = 4
|
||||||
|
TF_USE_DEFAULT_WORKER = 0
|
||||||
|
TF_USE_SYSTEM_THREAD = 16
|
||||||
|
TF_USE_KERNEL_APC = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
type TransmitFileBuffers struct {
|
||||||
|
Head uintptr
|
||||||
|
HeadLength uint32
|
||||||
|
Tail uintptr
|
||||||
|
TailLength uint32
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user