mirror of https://github.com/v2ray/v2ray-core
only yield goroutine after second write
parent
4b885f5775
commit
120058310a
|
@ -41,6 +41,7 @@ type pipe struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var errBufferFull = errors.New("buffer full")
|
var errBufferFull = errors.New("buffer full")
|
||||||
|
var errSlowDown = errors.New("slow down")
|
||||||
|
|
||||||
func (p *pipe) getState(forRead bool) error {
|
func (p *pipe) getState(forRead bool) error {
|
||||||
switch p.state {
|
switch p.state {
|
||||||
|
@ -122,11 +123,11 @@ func (p *pipe) writeMultiBufferInternal(mb buf.MultiBuffer) error {
|
||||||
|
|
||||||
if p.data == nil {
|
if p.data == nil {
|
||||||
p.data = mb
|
p.data = mb
|
||||||
} else {
|
return nil
|
||||||
p.data, _ = buf.MergeMulti(p.data, mb)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
p.data, _ = buf.MergeMulti(p.data, mb)
|
||||||
|
return errSlowDown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
func (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
|
@ -136,17 +137,25 @@ func (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
|
|
||||||
for {
|
for {
|
||||||
err := p.writeMultiBufferInternal(mb)
|
err := p.writeMultiBufferInternal(mb)
|
||||||
switch {
|
if err == nil {
|
||||||
case err == nil:
|
p.readSignal.Signal()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == errSlowDown {
|
||||||
p.readSignal.Signal()
|
p.readSignal.Signal()
|
||||||
|
|
||||||
// Yield current goroutine. Hopefully the reading counterpart can pick up the payload.
|
// Yield current goroutine. Hopefully the reading counterpart can pick up the payload.
|
||||||
runtime.Gosched()
|
runtime.Gosched()
|
||||||
return nil
|
return nil
|
||||||
case err == errBufferFull && p.option.discardOverflow:
|
}
|
||||||
|
|
||||||
|
if err == errBufferFull && p.option.discardOverflow {
|
||||||
buf.ReleaseMulti(mb)
|
buf.ReleaseMulti(mb)
|
||||||
return nil
|
return nil
|
||||||
case err != errBufferFull:
|
}
|
||||||
|
|
||||||
|
if err != errBufferFull {
|
||||||
buf.ReleaseMulti(mb)
|
buf.ReleaseMulti(mb)
|
||||||
p.readSignal.Signal()
|
p.readSignal.Signal()
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -17,14 +17,18 @@ func TestPipeReadWrite(t *testing.T) {
|
||||||
assert := With(t)
|
assert := With(t)
|
||||||
|
|
||||||
pReader, pWriter := New(WithSizeLimit(1024))
|
pReader, pWriter := New(WithSizeLimit(1024))
|
||||||
payload := []byte{'a', 'b', 'c', 'd'}
|
|
||||||
b := buf.New()
|
b := buf.New()
|
||||||
b.Write(payload)
|
b.WriteString("abcd")
|
||||||
assert(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}), IsNil)
|
assert(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}), IsNil)
|
||||||
|
|
||||||
|
b2 := buf.New()
|
||||||
|
b2.WriteString("efg")
|
||||||
|
assert(pWriter.WriteMultiBuffer(buf.MultiBuffer{b2}), IsNil)
|
||||||
|
|
||||||
rb, err := pReader.ReadMultiBuffer()
|
rb, err := pReader.ReadMultiBuffer()
|
||||||
assert(err, IsNil)
|
assert(err, IsNil)
|
||||||
assert(rb.String(), Equals, b.String())
|
assert(rb.String(), Equals, "abcdefg")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPipeCloseError(t *testing.T) {
|
func TestPipeCloseError(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue