mirror of
https://github.com/golang/go.git
synced 2026-04-03 01:40:30 +09:00
runtime/poll: fix race condition in Window's SendFile
The destination of SendFile is a socket, which doesn't support file offsets. There is no need to keep track of the file offset, and doing so causes a race between SendFile and Read. While here, make sure that SendFile tests do call poll.SendFile. Fixes #78015 Cq-Include-Trybots: luci.golang.try:gotip-windows-amd64-race,gotip-linux-amd64-race Change-Id: I8cce45c0c110e848d9bdbc5ba340b92ca041f0a4 Reviewed-on: https://go-review.googlesource.com/c/go/+/752860 Reviewed-by: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Reviewed-by: Mark Freeman <markfreeman@google.com>
This commit is contained in:
@@ -68,8 +68,8 @@ func SendFile(fd *FD, src uintptr, size int64) (written int64, err error, handle
|
||||
chunkSize = size
|
||||
}
|
||||
|
||||
fd.setOffset(startpos + written)
|
||||
n, err := fd.execIO('w', func(o *operation) (uint32, error) {
|
||||
o.setOffset(startpos + written)
|
||||
err := syscall.TransmitFile(fd.Sysfd, hsrc, uint32(chunkSize), 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var testHookSupportsSendfile func() bool
|
||||
|
||||
// sendFile copies the contents of r to c using the sendfile
|
||||
// system call to minimize copies.
|
||||
//
|
||||
|
||||
@@ -8,6 +8,8 @@ package net
|
||||
|
||||
import "io"
|
||||
|
||||
var testHookSupportsSendfile func() bool
|
||||
|
||||
func supportsSendfile() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -28,6 +28,16 @@ const (
|
||||
newtonSHA256 = "d4a9ac22462b35e7821a4f2706c211093da678620a8f9997989ee7cf8d507bbd"
|
||||
)
|
||||
|
||||
func hookSupportsSendfile(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
origHook := testHookSupportsSendfile
|
||||
testHookSupportsSendfile = func() bool { return true }
|
||||
t.Cleanup(func() {
|
||||
testHookSupportsSendfile = origHook
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// expectSendfile runs f, and verifies that internal/poll.SendFile successfully handles
|
||||
// a write to wantConn during f's execution.
|
||||
//
|
||||
@@ -35,6 +45,7 @@ const (
|
||||
// expect a call to SendFile.
|
||||
func expectSendfile(t *testing.T, wantConn Conn, f func()) {
|
||||
t.Helper()
|
||||
hookSupportsSendfile(t)
|
||||
if !supportsSendfile() {
|
||||
f()
|
||||
return
|
||||
|
||||
@@ -12,5 +12,8 @@ import "internal/syscall/windows"
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile
|
||||
// https://golang.org/issue/73746
|
||||
func supportsSendfile() bool {
|
||||
if testHookSupportsSendfile != nil {
|
||||
return testHookSupportsSendfile()
|
||||
}
|
||||
return windows.SupportUnlimitedTransmitFile()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user