Skip to content

Commit 35d1412

Browse files
committed
Fix vectorised writers
1 parent bc3fc9a commit 35d1412

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

common/bufio/vectorised_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package bufio
33
import (
44
"crypto/rand"
55
"io"
6+
"os"
67
"testing"
78

89
"github.com/stretchr/testify/require"
@@ -26,6 +27,8 @@ func TestWriteVectorised(t *testing.T) {
2627
finish := Timeout(t)
2728
_, err = WriteVectorised(vectorisedWriter, [][]byte{bufA[:], bufB[:]})
2829
require.NoError(t, err)
30+
_, err = WriteVectorised(vectorisedWriter, [][]byte{})
31+
require.Error(t, err, os.ErrInvalid)
2932
output := make([]byte, 2048)
3033
_, err = io.ReadFull(outputConn, output)
3134
finish()

common/bufio/vectorised_unix.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,14 @@ func (w *SyscallVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error {
2525
defer buf.ReleaseMulti(buffers)
2626
iovecList := w.iovecList
2727
for _, buffer := range buffers {
28+
if buffer.IsEmpty() {
29+
continue
30+
}
2831
iovecList = append(iovecList, buffer.Iovec(buffer.Len()))
2932
}
30-
if cap(iovecList) > cap(w.iovecList) {
33+
if len(iovecList) == 0 {
34+
return os.ErrInvalid
35+
} else if cap(iovecList) > cap(w.iovecList) {
3136
w.iovecList = iovecList[:0]
3237
}
3338
var innerErr unix.Errno
@@ -37,16 +42,14 @@ func (w *SyscallVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error {
3742
var r0 uintptr
3843
//nolint:staticcheck
3944
r0, _, innerErr = unix.RawSyscall(unix.SYS_WRITEV, fd, uintptr(unsafe.Pointer(&writeIovecList[0])), uintptr(len(writeIovecList)))
40-
writeN := int(r0)
41-
for writeN > 0 {
42-
if buffers[0].Len() > writeN {
43-
buffers[0].Advance(writeN)
44-
writeIovecList[0] = buffers[0].Iovec(buffers[0].Len())
45+
writeN := uint64(r0)
46+
for writeN > 0 && len(writeIovecList) > 0 {
47+
if uint64(writeIovecList[0].Len) > writeN {
48+
writeIovecList[0].Base = (*byte)(unsafe.Add(unsafe.Pointer(writeIovecList[0].Base), writeN))
49+
writeIovecList[0].SetLen(int(uint64(writeIovecList[0].Len) - writeN))
4550
break
4651
} else {
47-
writeN -= buffers[0].Len()
48-
buffers[0].Release()
49-
buffers = buffers[1:]
52+
writeN -= uint64(writeIovecList[0].Len)
5053
writeIovecList = writeIovecList[1:]
5154
}
5255
}
@@ -69,6 +72,9 @@ func (w *SyscallVectorisedPacketWriter) WriteVectorisedPacket(buffers []*buf.Buf
6972
defer buf.ReleaseMulti(buffers)
7073
iovecList := w.iovecList
7174
for _, buffer := range buffers {
75+
if buffer.IsEmpty() {
76+
continue
77+
}
7278
iovecList = append(iovecList, buffer.Iovec(buffer.Len()))
7379
}
7480
if cap(iovecList) > cap(w.iovecList) {

common/bufio/vectorised_windows.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,22 @@ func (w *SyscallVectorisedPacketWriter) WriteVectorisedPacket(buffers []*buf.Buf
4545
defer buf.ReleaseMulti(buffers)
4646
iovecList := w.iovecList
4747
for _, buffer := range buffers {
48+
if buffer.IsEmpty() {
49+
continue
50+
}
4851
iovecList = append(iovecList, buffer.Iovec(buffer.Len()))
4952
}
5053
var n uint32
5154
var innerErr error
5255
err := w.rawConn.Write(func(fd uintptr) (done bool) {
5356
name, nameLen := ToSockaddr(destination.AddrPort())
57+
var bufs *windows.WSABuf
58+
if len(iovecList) > 0 {
59+
bufs = &iovecList[0]
60+
}
5461
innerErr = windows.WSASendTo(
5562
windows.Handle(fd),
56-
&iovecList[0],
63+
bufs,
5764
uint32(len(iovecList)),
5865
&n,
5966
0,

0 commit comments

Comments
 (0)