refactor multibuffer

pull/1435/head
Darien Raymond 2018-11-18 19:36:36 +01:00
parent 0f324a613e
commit 842a089dad
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
19 changed files with 147 additions and 161 deletions

View File

@ -32,12 +32,10 @@ func TestStatsWriter(t *testing.T) {
Writer: buf.Discard, Writer: buf.Discard,
} }
var mb buf.MultiBuffer mb := buf.MergeBytes(nil, []byte("abcd"))
common.Must2(mb.Write([]byte("abcd")))
common.Must(writer.WriteMultiBuffer(mb)) common.Must(writer.WriteMultiBuffer(mb))
mb = buf.ReleaseMulti(mb) mb = buf.MergeBytes(nil, []byte("efg"))
common.Must2(mb.Write([]byte("efg")))
common.Must(writer.WriteMultiBuffer(mb)) common.Must(writer.WriteMultiBuffer(mb))
if c.Value() != 7 { if c.Value() != 7 {

View File

@ -251,8 +251,7 @@ func (w *PortalWorker) heartbeat() error {
b, err := proto.Marshal(msg) b, err := proto.Marshal(msg)
common.Must(err) common.Must(err)
var mb buf.MultiBuffer mb := buf.MergeBytes(nil, b)
common.Must2(mb.Write(b))
return w.writer.WriteMultiBuffer(mb) return w.writer.WriteMultiBuffer(mb)
} }

View File

@ -8,21 +8,9 @@ import (
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
) )
// ReadAllToMultiBuffer reads all content from the reader into a MultiBuffer, until EOF.
func ReadAllToMultiBuffer(reader io.Reader) (MultiBuffer, error) {
mb := make(MultiBuffer, 0, 128)
if _, err := mb.ReadFrom(reader); err != nil {
ReleaseMulti(mb)
return nil, err
}
return mb, nil
}
// ReadAllToBytes reads all content from the reader into a byte array, until EOF. // ReadAllToBytes reads all content from the reader into a byte array, until EOF.
func ReadAllToBytes(reader io.Reader) ([]byte, error) { func ReadAllToBytes(reader io.Reader) ([]byte, error) {
mb, err := ReadAllToMultiBuffer(reader) mb, err := ReadFrom(reader)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -30,7 +18,8 @@ func ReadAllToBytes(reader io.Reader) ([]byte, error) {
return nil, nil return nil, nil
} }
b := make([]byte, mb.Len()) b := make([]byte, mb.Len())
common.Must2(mb.Read(b)) mb, _, err = SplitBytes(mb, b)
common.Must(err)
ReleaseMulti(mb) ReleaseMulti(mb)
return b, nil return b, nil
} }
@ -47,6 +36,23 @@ func MergeMulti(dest MultiBuffer, src MultiBuffer) (MultiBuffer, MultiBuffer) {
return dest, src[:0] return dest, src[:0]
} }
func MergeBytes(dest MultiBuffer, src []byte) MultiBuffer {
n := len(dest)
if n > 0 && !(dest)[n-1].IsFull() {
nBytes, _ := (dest)[n-1].Write(src)
src = src[nBytes:]
}
for len(src) > 0 {
b := New()
nBytes, _ := b.Write(src)
src = src[nBytes:]
dest = append(dest, b)
}
return dest
}
// ReleaseMulti release all content of the MultiBuffer, and returns an empty MultiBuffer. // ReleaseMulti release all content of the MultiBuffer, and returns an empty MultiBuffer.
func ReleaseMulti(mb MultiBuffer) MultiBuffer { func ReleaseMulti(mb MultiBuffer) MultiBuffer {
for i := range mb { for i := range mb {
@ -69,93 +75,42 @@ func (mb MultiBuffer) Copy(b []byte) int {
return total return total
} }
// ReadFrom implements io.ReaderFrom. // ReadFrom reads all content from reader until EOF.
func (mb *MultiBuffer) ReadFrom(reader io.Reader) (int64, error) { func ReadFrom(reader io.Reader) (MultiBuffer, error) {
totalBytes := int64(0) mb := make(MultiBuffer, 0, 16)
for { for {
b := New() b := New()
_, err := b.ReadFullFrom(reader, Size) _, err := b.ReadFullFrom(reader, Size)
if b.IsEmpty() { if b.IsEmpty() {
b.Release() b.Release()
} else { } else {
*mb = append(*mb, b) mb = append(mb, b)
} }
totalBytes += int64(b.Len())
if err != nil { if err != nil {
if errors.Cause(err) == io.EOF || errors.Cause(err) == io.ErrUnexpectedEOF { if errors.Cause(err) == io.EOF || errors.Cause(err) == io.ErrUnexpectedEOF {
return totalBytes, nil return mb, nil
} }
return totalBytes, err return mb, err
} }
} }
} }
// Read implements io.Reader. func SplitBytes(mb MultiBuffer, b []byte) (MultiBuffer, int, error) {
func (mb *MultiBuffer) Read(b []byte) (int, error) {
if mb.IsEmpty() {
return 0, io.EOF
}
endIndex := len(*mb)
totalBytes := 0 totalBytes := 0
for i, bb := range *mb {
for len(mb) > 0 {
bb := mb[0]
nBytes, _ := bb.Read(b) nBytes, _ := bb.Read(b)
totalBytes += nBytes totalBytes += nBytes
b = b[nBytes:] b = b[nBytes:]
if bb.IsEmpty() { if !bb.IsEmpty() {
bb.Release()
(*mb)[i] = nil
} else {
endIndex = i
break break
} }
} bb.Release()
*mb = (*mb)[endIndex:] mb = mb[1:]
return totalBytes, nil
}
// WriteTo implements io.WriterTo.
func (mb *MultiBuffer) WriteTo(writer io.Writer) (int64, error) {
defer func() {
*mb = ReleaseMulti(*mb)
}()
totalBytes := int64(0)
for _, b := range *mb {
nBytes, err := writer.Write(b.Bytes())
totalBytes += int64(nBytes)
if err != nil {
return totalBytes, err
}
} }
return totalBytes, nil return mb, totalBytes, nil
}
// Write implements io.Writer.
func (mb *MultiBuffer) Write(b []byte) (int, error) {
totalBytes := len(b)
n := len(*mb)
if n > 0 && !(*mb)[n-1].IsFull() {
nBytes, _ := (*mb)[n-1].Write(b)
b = b[nBytes:]
}
for len(b) > 0 {
bb := New()
nBytes, _ := bb.Write(b)
b = b[nBytes:]
*mb = append(*mb, bb)
}
return totalBytes, nil
}
// WriteMultiBuffer implements Writer.
func (mb *MultiBuffer) WriteMultiBuffer(b MultiBuffer) error {
*mb, _ = MergeMulti(*mb, b)
return nil
} }
// Len returns the total number of bytes in the MultiBuffer. // Len returns the total number of bytes in the MultiBuffer.
@ -223,3 +178,39 @@ func (mb *MultiBuffer) SplitFirst() *Buffer {
*mb = (*mb)[1:] *mb = (*mb)[1:]
return b return b
} }
type MultiBufferContainer struct {
MultiBuffer
}
func (c *MultiBufferContainer) Read(b []byte) (int, error) {
if c.MultiBuffer.IsEmpty() {
return 0, io.EOF
}
mb, nBytes, err := SplitBytes(c.MultiBuffer, b)
c.MultiBuffer = mb
return nBytes, err
}
func (c *MultiBufferContainer) ReadMultiBuffer() (MultiBuffer, error) {
mb := c.MultiBuffer
c.MultiBuffer = nil
return mb, nil
}
func (c *MultiBufferContainer) Write(b []byte) (int, error) {
c.MultiBuffer = MergeBytes(c.MultiBuffer, b)
return len(b), nil
}
func (c *MultiBufferContainer) WriteMultiBuffer(b MultiBuffer) error {
mb, _ := MergeMulti(c.MultiBuffer, b)
c.MultiBuffer = mb
return nil
}
func (c *MultiBufferContainer) Close() error {
c.MultiBuffer = ReleaseMulti(c.MultiBuffer)
return nil
}

View File

@ -21,7 +21,7 @@ func TestMultiBufferRead(t *testing.T) {
mb := MultiBuffer{b1, b2} mb := MultiBuffer{b1, b2}
bs := make([]byte, 32) bs := make([]byte, 32)
nBytes, err := mb.Read(bs) _, nBytes, err := SplitBytes(mb, bs)
assert(err, IsNil) assert(err, IsNil)
assert(nBytes, Equals, 4) assert(nBytes, Equals, 4)
assert(bs[:nBytes], Equals, []byte("abcd")) assert(bs[:nBytes], Equals, []byte("abcd"))
@ -43,16 +43,8 @@ func TestMultiBufferSliceBySizeLarge(t *testing.T) {
lb := make([]byte, 8*1024) lb := make([]byte, 8*1024)
common.Must2(io.ReadFull(rand.Reader, lb)) common.Must2(io.ReadFull(rand.Reader, lb))
var mb MultiBuffer mb := MergeBytes(nil, lb)
common.Must2(mb.Write(lb))
mb2 := mb.SliceBySize(1024) mb2 := mb.SliceBySize(1024)
assert(mb2.Len(), Equals, int32(1024)) assert(mb2.Len(), Equals, int32(1024))
} }
func TestInterface(t *testing.T) {
assert := With(t)
assert((*MultiBuffer)(nil), Implements, (*io.WriterTo)(nil))
assert((*MultiBuffer)(nil), Implements, (*io.ReaderFrom)(nil))
}

View File

@ -46,8 +46,9 @@ func (r *BufferedReader) ReadByte() (byte, error) {
// Read implements io.Reader. It reads from internal buffer first (if available) and then reads from the underlying reader. // Read implements io.Reader. It reads from internal buffer first (if available) and then reads from the underlying reader.
func (r *BufferedReader) Read(b []byte) (int, error) { func (r *BufferedReader) Read(b []byte) (int, error) {
if !r.Buffer.IsEmpty() { if !r.Buffer.IsEmpty() {
nBytes, err := r.Buffer.Read(b) buffer, nBytes, err := SplitBytes(r.Buffer, b)
common.Must(err) common.Must(err)
r.Buffer = buffer
if r.Buffer.IsEmpty() { if r.Buffer.IsEmpty() {
r.Buffer = nil r.Buffer = nil
} }
@ -59,12 +60,12 @@ func (r *BufferedReader) Read(b []byte) (int, error) {
return 0, err return 0, err
} }
nBytes, err := mb.Read(b) mb, nBytes, err := SplitBytes(mb, b)
common.Must(err) common.Must(err)
if !mb.IsEmpty() { if !mb.IsEmpty() {
r.Buffer = mb r.Buffer = mb
} }
return nBytes, err return nBytes, nil
} }
// ReadMultiBuffer implements Reader. // ReadMultiBuffer implements Reader.

View File

@ -69,8 +69,7 @@ func TestReadByte(t *testing.T) {
t.Error("unexpected byte: ", b, " want a") t.Error("unexpected byte: ", b, " want a")
} }
var mb MultiBuffer nBytes, err := reader.WriteTo(DiscardBytes)
nBytes, err := reader.WriteTo(&mb)
common.Must(err) common.Must(err)
if nBytes != 3 { if nBytes != 3 {
t.Error("unexpect bytes written: ", nBytes) t.Error("unexpect bytes written: ", nBytes)

View File

@ -33,8 +33,7 @@ func TestReadvReader(t *testing.T) {
go func() { go func() {
writer := NewWriter(conn) writer := NewWriter(conn)
var mb MultiBuffer mb := MergeBytes(nil, data)
common.Must2(mb.Write(data))
if err := writer.WriteMultiBuffer(mb); err != nil { if err := writer.WriteMultiBuffer(mb); err != nil {
t.Fatal("failed to write data: ", err) t.Fatal("failed to write data: ", err)
@ -58,7 +57,8 @@ func TestReadvReader(t *testing.T) {
} }
rdata := make([]byte, size) rdata := make([]byte, size)
common.Must2(rmb.Read(rdata)) _, _, err = SplitBytes(rmb, rdata)
common.Must(err)
if err := compare.BytesEqualWithDetail(data, rdata); err != nil { if err := compare.BytesEqualWithDetail(data, rdata); err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -134,15 +134,16 @@ func (w *BufferedWriter) WriteMultiBuffer(b MultiBuffer) error {
return w.writer.WriteMultiBuffer(b) return w.writer.WriteMultiBuffer(b)
} }
defer ReleaseMulti(b) reader := MultiBufferContainer{
MultiBuffer: b,
}
defer reader.Close()
for !b.IsEmpty() { for !reader.MultiBuffer.IsEmpty() {
if w.buffer == nil { if w.buffer == nil {
w.buffer = New() w.buffer = New()
} }
if _, err := w.buffer.ReadFrom(&b); err != nil { common.Must2(w.buffer.ReadFrom(&reader))
return err
}
if w.buffer.IsFull() { if w.buffer.IsFull() {
if err := w.flushInternal(); err != nil { if err := w.flushInternal(); err != nil {
return err return err

View File

@ -194,7 +194,7 @@ func (r *AuthenticationReader) readInternal(soft bool, mb *buf.MultiBuffer) erro
return err return err
} }
common.Must2(mb.Write(rb)) *mb = buf.MergeBytes(*mb, rb)
return nil return nil
} }
@ -279,11 +279,17 @@ func (w *AuthenticationWriter) writeStream(mb buf.MultiBuffer) error {
payloadSize := buf.Size - int32(w.auth.Overhead()) - w.sizeParser.SizeBytes() - maxPadding payloadSize := buf.Size - int32(w.auth.Overhead()) - w.sizeParser.SizeBytes() - maxPadding
mb2Write := make(buf.MultiBuffer, 0, len(mb)+10) mb2Write := make(buf.MultiBuffer, 0, len(mb)+10)
temp := buf.New()
defer temp.Release()
rawBytes := temp.Extend(payloadSize)
for { for {
b := buf.New() nb, nBytes, err := buf.SplitBytes(mb, rawBytes)
common.Must2(b.ReadFrom(io.LimitReader(&mb, int64(payloadSize)))) common.Must(err)
eb, err := w.seal(b.Bytes()) mb = nb
b.Release()
eb, err := w.seal(rawBytes[:nBytes])
if err != nil { if err != nil {
buf.ReleaseMulti(mb2Write) buf.ReleaseMulti(mb2Write)

View File

@ -30,8 +30,7 @@ func TestAuthenticationReaderWriter(t *testing.T) {
rawPayload := make([]byte, payloadSize) rawPayload := make([]byte, payloadSize)
rand.Read(rawPayload) rand.Read(rawPayload)
var payload buf.MultiBuffer payload := buf.MergeBytes(nil, rawPayload)
payload.Write(rawPayload)
assert(payload.Len(), Equals, int32(payloadSize)) assert(payload.Len(), Equals, int32(payloadSize))
cache := bytes.NewBuffer(nil) cache := bytes.NewBuffer(nil)
@ -66,7 +65,7 @@ func TestAuthenticationReaderWriter(t *testing.T) {
assert(mb.Len(), Equals, int32(payloadSize)) assert(mb.Len(), Equals, int32(payloadSize))
mbContent := make([]byte, payloadSize) mbContent := make([]byte, payloadSize)
mb.Read(mbContent) buf.SplitBytes(mb, mbContent)
assert(mbContent, Equals, rawPayload) assert(mbContent, Equals, rawPayload)
_, err = reader.ReadMultiBuffer() _, err = reader.ReadMultiBuffer()

View File

@ -100,7 +100,7 @@ func (c *connection) Write(b []byte) (int, error) {
l := len(b) l := len(b)
mb := make(buf.MultiBuffer, 0, l/buf.Size+1) mb := make(buf.MultiBuffer, 0, l/buf.Size+1)
common.Must2(mb.Write(b)) mb = buf.MergeBytes(mb, b)
return l, c.writer.WriteMultiBuffer(mb) return l, c.writer.WriteMultiBuffer(mb)
} }

View File

@ -17,8 +17,8 @@ func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
return nil, newError("v2ctl doesn't exist").Base(err) return nil, newError("v2ctl doesn't exist").Base(err)
} }
errBuffer := buf.MultiBuffer{} var errBuffer buf.MultiBufferContainer
outBuffer := buf.MultiBuffer{} var outBuffer buf.MultiBufferContainer
cmd := exec.Command(v2ctl, args...) cmd := exec.Command(v2ctl, args...)
cmd.Stderr = &errBuffer cmd.Stderr = &errBuffer
@ -35,12 +35,10 @@ func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
if err := cmd.Wait(); err != nil { if err := cmd.Wait(); err != nil {
msg := "failed to execute v2ctl" msg := "failed to execute v2ctl"
if errBuffer.Len() > 0 { if errBuffer.Len() > 0 {
msg += ": " + errBuffer.String() msg += ": " + errBuffer.MultiBuffer.String()
} }
buf.ReleaseMulti(errBuffer)
buf.ReleaseMulti(outBuffer)
return nil, newError(msg).Base(err) return nil, newError(msg).Base(err)
} }
return outBuffer, nil return outBuffer.MultiBuffer, nil
} }

View File

@ -12,16 +12,6 @@ import (
//go:generate errorgen //go:generate errorgen
type ClosableMultiBuffer struct {
buf.MultiBuffer
}
func (c *ClosableMultiBuffer) Close() error {
buf.ReleaseMulti(c.MultiBuffer)
c.MultiBuffer = nil
return nil
}
func loadConfigFile(configFile string) (io.ReadCloser, error) { func loadConfigFile(configFile string) (io.ReadCloser, error) {
if configFile == "stdin:" { if configFile == "stdin:" {
return os.Stdin, nil return os.Stdin, nil
@ -32,7 +22,9 @@ func loadConfigFile(configFile string) (io.ReadCloser, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &ClosableMultiBuffer{content}, nil return &buf.MultiBufferContainer{
MultiBuffer: content,
}, nil
} }
fixedFile := os.ExpandEnv(configFile) fixedFile := os.ExpandEnv(configFile)
@ -42,12 +34,13 @@ func loadConfigFile(configFile string) (io.ReadCloser, error) {
} }
defer file.Close() defer file.Close()
content, err := buf.ReadAllToMultiBuffer(file) content, err := buf.ReadFrom(file)
if err != nil { if err != nil {
return nil, newError("failed to load config file: ", fixedFile).Base(err).AtWarning() return nil, newError("failed to load config file: ", fixedFile).Base(err).AtWarning()
} }
return &ClosableMultiBuffer{content}, nil return &buf.MultiBufferContainer{
MultiBuffer: content,
}, nil
} }
func init() { func init() {

View File

@ -7,6 +7,7 @@ import (
"v2ray.com/core" "v2ray.com/core"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/platform/ctlcmd" "v2ray.com/core/common/platform/ctlcmd"
) )
@ -19,7 +20,9 @@ func init() {
if err != nil { if err != nil {
return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning() return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning()
} }
return core.LoadConfig("protobuf", "", &jsonContent) return core.LoadConfig("protobuf", "", &buf.MultiBufferContainer{
MultiBuffer: jsonContent,
})
}, },
})) }))
} }

View File

@ -185,8 +185,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
} }
if reader.Buffered() > 0 { if reader.Buffered() > 0 {
var payload buf.MultiBuffer payload, err := buf.ReadFrom(io.LimitReader(reader, int64(reader.Buffered())))
_, err := payload.ReadFrom(&io.LimitedReader{R: reader, N: int64(reader.Buffered())})
if err != nil { if err != nil {
return err return err
} }

View File

@ -92,8 +92,7 @@ func (v *ChunkReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
return nil, newError("invalid auth") return nil, newError("invalid auth")
} }
var mb buf.MultiBuffer mb := buf.MergeBytes(nil, payload)
common.Must2(mb.Write(payload))
return mb, nil return mb, nil
} }
@ -117,7 +116,7 @@ func (w *ChunkWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
defer buf.ReleaseMulti(mb) defer buf.ReleaseMulti(mb)
for { for {
payloadLen, _ := mb.Read(w.buffer[2+AuthSize:]) mb, payloadLen, _ := buf.SplitBytes(mb, w.buffer[2+AuthSize:])
binary.BigEndian.PutUint16(w.buffer, uint16(payloadLen)) binary.BigEndian.PutUint16(w.buffer, uint16(payloadLen))
w.auth.Authenticate(w.buffer[2+AuthSize:2+AuthSize+payloadLen], w.buffer[2:]) w.auth.Authenticate(w.buffer[2+AuthSize:2+AuthSize+payloadLen], w.buffer[2:])
if err := buf.WriteAllBytes(w.writer, w.buffer[:2+AuthSize+payloadLen]); err != nil { if err := buf.WriteAllBytes(w.writer, w.buffer[:2+AuthSize+payloadLen]); err != nil {

View File

@ -1,6 +1,7 @@
package kcp package kcp
import ( import (
"bytes"
"io" "io"
"net" "net"
"runtime" "runtime"
@ -8,7 +9,6 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/signal" "v2ray.com/core/common/signal"
"v2ray.com/core/common/signal/semaphore" "v2ray.com/core/common/signal/semaphore"
@ -364,12 +364,8 @@ func (c *Connection) waitForDataOutput() error {
// Write implements io.Writer. // Write implements io.Writer.
func (c *Connection) Write(b []byte) (int, error) { func (c *Connection) Write(b []byte) (int, error) {
// This involves multiple copies of the buffer. But we don't expect this method to be used often. reader := bytes.NewReader(b)
// Only wrapped connections such as TLS and WebSocket will call into this. if err := c.writeMultiBufferInternal(reader); err != nil {
// TODO: improve efficiency.
var mb buf.MultiBuffer
common.Must2(mb.Write(b))
if err := c.WriteMultiBuffer(mb); err != nil {
return 0, err return 0, err
} }
return len(b), nil return len(b), nil
@ -377,8 +373,15 @@ func (c *Connection) Write(b []byte) (int, error) {
// WriteMultiBuffer implements buf.Writer. // WriteMultiBuffer implements buf.Writer.
func (c *Connection) WriteMultiBuffer(mb buf.MultiBuffer) error { func (c *Connection) WriteMultiBuffer(mb buf.MultiBuffer) error {
defer buf.ReleaseMulti(mb) reader := &buf.MultiBufferContainer{
MultiBuffer: mb,
}
defer reader.Close()
return c.writeMultiBufferInternal(reader)
}
func (c *Connection) writeMultiBufferInternal(reader io.Reader) error {
updatePending := false updatePending := false
defer func() { defer func() {
if updatePending { if updatePending {
@ -386,19 +389,28 @@ func (c *Connection) WriteMultiBuffer(mb buf.MultiBuffer) error {
} }
}() }()
var b *buf.Buffer
defer b.Release()
for { for {
for { for {
if c == nil || c.State() != StateActive { if c == nil || c.State() != StateActive {
return io.ErrClosedPipe return io.ErrClosedPipe
} }
if !c.sendingWorker.Push(&mb) { if b == nil {
b = buf.New()
_, err := b.ReadFrom(io.LimitReader(reader, int64(c.mss)))
if err != nil {
return nil
}
}
if !c.sendingWorker.Push(b) {
break break
} }
updatePending = true updatePending = true
if mb.IsEmpty() { b = nil
return nil
}
} }
if updatePending { if updatePending {

View File

@ -209,7 +209,7 @@ func (w *ReceivingWorker) Read(b []byte) int {
if mb.IsEmpty() { if mb.IsEmpty() {
return 0 return 0
} }
nBytes, err := mb.Read(b) mb, nBytes, err := buf.SplitBytes(mb, b)
common.Must(err) common.Must(err)
if !mb.IsEmpty() { if !mb.IsEmpty() {
w.leftOver = mb w.leftOver = mb

View File

@ -2,10 +2,8 @@ package kcp
import ( import (
"container/list" "container/list"
"io"
"sync" "sync"
"v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
) )
@ -262,7 +260,7 @@ func (w *SendingWorker) ProcessSegment(current uint32, seg *AckSegment, rto uint
} }
} }
func (w *SendingWorker) Push(mb *buf.MultiBuffer) bool { func (w *SendingWorker) Push(b *buf.Buffer) bool {
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
@ -274,8 +272,6 @@ func (w *SendingWorker) Push(mb *buf.MultiBuffer) bool {
return false return false
} }
b := buf.New()
common.Must2(b.ReadFrom(io.LimitReader(mb, int64(w.conn.mss))))
w.window.Push(w.nextNumber, b) w.window.Push(w.nextNumber, b)
w.nextNumber++ w.nextNumber++
return true return true