split read and write signal

pull/298/merge v2.27.1
Darien Raymond 2017-05-15 20:42:10 +02:00
parent 642a630912
commit ad35fc7028
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
1 changed files with 39 additions and 22 deletions

View File

@ -58,7 +58,8 @@ type Stream struct {
data buf.MultiBuffer data buf.MultiBuffer
size uint64 size uint64
ctx context.Context ctx context.Context
wakeup chan bool readSignal chan bool
writeSignal chan bool
close bool close bool
err bool err bool
} }
@ -66,7 +67,8 @@ type Stream struct {
func NewStream(ctx context.Context) *Stream { func NewStream(ctx context.Context) *Stream {
return &Stream{ return &Stream{
ctx: ctx, ctx: ctx,
wakeup: make(chan bool, 1), readSignal: make(chan bool, 1),
writeSignal: make(chan bool, 1),
size: 0, size: 0,
} }
} }
@ -110,14 +112,14 @@ func (s *Stream) Read() (buf.MultiBuffer, error) {
} }
if mb != nil { if mb != nil {
s.wakeUp() s.notifyRead()
return mb, nil return mb, nil
} }
select { select {
case <-s.ctx.Done(): case <-s.ctx.Done():
return nil, io.EOF return nil, io.EOF
case <-s.wakeup: case <-s.writeSignal:
} }
} }
} }
@ -130,7 +132,7 @@ func (s *Stream) ReadTimeout(timeout time.Duration) (buf.MultiBuffer, error) {
} }
if mb != nil { if mb != nil {
s.wakeUp() s.notifyRead()
return mb, nil return mb, nil
} }
@ -139,7 +141,7 @@ func (s *Stream) ReadTimeout(timeout time.Duration) (buf.MultiBuffer, error) {
return nil, io.EOF return nil, io.EOF
case <-time.After(timeout): case <-time.After(timeout):
return nil, buf.ErrReadTimeout return nil, buf.ErrReadTimeout
case <-s.wakeup: case <-s.writeSignal:
} }
} }
} }
@ -149,13 +151,18 @@ func (s *Stream) Write(data buf.MultiBuffer) error {
return nil return nil
} }
L:
for streamSizeLimit > 0 && s.size >= streamSizeLimit { for streamSizeLimit > 0 && s.size >= streamSizeLimit {
select { select {
case <-s.ctx.Done(): case <-s.ctx.Done():
return io.ErrClosedPipe return io.ErrClosedPipe
case <-s.wakeup: case <-s.readSignal:
break L s.access.RLock()
if s.err || s.close {
data.Release()
s.access.RUnlock()
return io.ErrClosedPipe
}
s.access.RUnlock()
} }
} }
@ -173,14 +180,21 @@ L:
s.data.AppendMulti(data) s.data.AppendMulti(data)
} }
s.size += uint64(data.Len()) s.size += uint64(data.Len())
s.wakeUp() s.notifyWrite()
return nil return nil
} }
func (s *Stream) wakeUp() { func (s *Stream) notifyRead() {
select { select {
case s.wakeup <- true: case s.readSignal <- true:
default:
}
}
func (s *Stream) notifyWrite() {
select {
case s.writeSignal <- true:
default: default:
} }
} }
@ -188,7 +202,8 @@ func (s *Stream) wakeUp() {
func (s *Stream) Close() { func (s *Stream) Close() {
s.access.Lock() s.access.Lock()
s.close = true s.close = true
s.wakeUp() s.notifyRead()
s.notifyWrite()
s.access.Unlock() s.access.Unlock()
} }
@ -198,7 +213,9 @@ func (s *Stream) CloseError() {
if s.data != nil { if s.data != nil {
s.data.Release() s.data.Release()
s.data = nil s.data = nil
s.size = 0
} }
s.wakeUp() s.notifyRead()
s.notifyWrite()
s.access.Unlock() s.access.Unlock()
} }