mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-10-16 22:00:53 +08:00

在四点链接的情况下,我们只终端中间两点是不够的,要切三刀; 总之实践很简单,就是copy完成之后,要Close所有的链接 readv的话,系统readv数组和buffer不要在put进pool后相互引用 添加-bl 选项,可以自定义buf大小;注意越小可能越慢,建议buf大小保持在4k以上 添加-pp选项,可以生成cpu.pprof文件 修复其它小问题.
56 lines
1.2 KiB
Go
56 lines
1.2 KiB
Go
//go:build !windows && !wasm && !illumos
|
||
// +build !windows,!wasm,!illumos
|
||
|
||
package utils
|
||
|
||
import (
|
||
"syscall"
|
||
"unsafe"
|
||
)
|
||
|
||
func GetReadVReader() SystemReadver {
|
||
return &posixReader{}
|
||
}
|
||
|
||
type posixReader struct {
|
||
iovecs []syscall.Iovec
|
||
}
|
||
|
||
func (r *posixReader) Init(bs [][]byte, singleBufLen int) {
|
||
iovecs := r.iovecs
|
||
if iovecs == nil {
|
||
iovecs = make([]syscall.Iovec, 0, len(bs))
|
||
}
|
||
for idx, b := range bs {
|
||
iovecs = append(iovecs, syscall.Iovec{
|
||
Base: &(b[0]),
|
||
})
|
||
iovecs[idx].SetLen(singleBufLen)
|
||
}
|
||
r.iovecs = iovecs
|
||
}
|
||
|
||
//正常readv返回的应该是 ssize_t, 在64位机器上应该是 int64, 但是负数只用于返回-1错误,而且我们提供的buffer长度远远小于 uint32的上限;所以uint32可以
|
||
func (r *posixReader) Read(fd uintptr) (uint32, error) {
|
||
n, _, e := syscall.Syscall(syscall.SYS_READV, fd, uintptr(unsafe.Pointer(&r.iovecs[0])), uintptr(len(r.iovecs)))
|
||
if e != 0 {
|
||
return 0, e
|
||
}
|
||
return uint32(n), nil
|
||
}
|
||
|
||
func (r *posixReader) Clear() {
|
||
for idx := range r.iovecs {
|
||
r.iovecs[idx].Base = nil
|
||
}
|
||
r.iovecs = r.iovecs[:0]
|
||
}
|
||
|
||
func (r *posixReader) Recover(bsLen int, bs [][]byte) {
|
||
r.iovecs = r.iovecs[:len(bs)]
|
||
|
||
for idx := range r.iovecs {
|
||
r.iovecs[idx].Base = &(bs[idx][0])
|
||
}
|
||
}
|