Fix ioloop groutine leaks bug. (#136)

* Fix ioloop groutine leaks bug.

* fix func (o *Operation) ioloop()  L:125 hangs
This commit is contained in:
soopsio 2017-12-08 09:17:16 +08:00 committed by chzyer
parent 40d6036c33
commit f6d7a1f6fb
5 changed files with 20 additions and 10 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.vscode/*

View File

@ -72,7 +72,7 @@ func NewOperation(t *Terminal, cfg *Config) *Operation {
t: t, t: t,
buf: NewRuneBuffer(t, cfg.Prompt, cfg, width), buf: NewRuneBuffer(t, cfg.Prompt, cfg, width),
outchan: make(chan []rune), outchan: make(chan []rune),
errchan: make(chan error), errchan: make(chan error, 1),
} }
op.w = op.buf.w op.w = op.buf.w
op.SetConfig(cfg) op.SetConfig(cfg)

View File

@ -54,7 +54,7 @@ type Config struct {
FuncGetWidth func() int FuncGetWidth func() int
Stdin io.Reader Stdin io.ReadCloser
StdinWriter io.Writer StdinWriter io.Writer
Stdout io.Writer Stdout io.Writer
Stderr io.Writer Stderr io.Writer
@ -274,6 +274,7 @@ func (i *Instance) Close() error {
if err := i.Terminal.Close(); err != nil { if err := i.Terminal.Close(); err != nil {
return err return err
} }
i.Config.Stdin.Close()
i.Operation.Close() i.Operation.Close()
return nil return nil
} }

View File

@ -189,11 +189,12 @@ loop:
} }
} }
func (r *RemoteSvr) Close() { func (r *RemoteSvr) Close() error {
if atomic.CompareAndSwapInt32(&r.closed, 0, 1) { if atomic.CompareAndSwapInt32(&r.closed, 0, 1) {
close(r.stopChan) close(r.stopChan)
r.conn.Close() r.conn.Close()
} }
return nil
} }
func (r *RemoteSvr) readLoop(buf *bufio.Reader) { func (r *RemoteSvr) readLoop(buf *bufio.Reader) {

21
std.go
View File

@ -137,14 +137,13 @@ func (c *CancelableStdin) Close() error {
type FillableStdin struct { type FillableStdin struct {
sync.Mutex sync.Mutex
stdin io.Reader stdin io.Reader
stdinBuffer io.Reader stdinBuffer io.ReadCloser
buf []byte buf []byte
bufErr error bufErr error
} }
// NewFillableStdin gives you FillableStdin // NewFillableStdin gives you FillableStdin
func NewFillableStdin(stdin io.Reader) (io.Reader, io.Writer) { func NewFillableStdin(stdin io.Reader) (io.ReadCloser, io.Writer) {
r, w := io.Pipe() r, w := io.Pipe()
s := &FillableStdin{ s := &FillableStdin{
stdinBuffer: r, stdinBuffer: r,
@ -152,7 +151,6 @@ func NewFillableStdin(stdin io.Reader) (io.Reader, io.Writer) {
} }
s.ioloop() s.ioloop()
return s, w return s, w
} }
func (s *FillableStdin) ioloop() { func (s *FillableStdin) ioloop() {
@ -161,6 +159,11 @@ func (s *FillableStdin) ioloop() {
bufR := make([]byte, 100) bufR := make([]byte, 100)
var n int var n int
n, s.bufErr = s.stdinBuffer.Read(bufR) n, s.bufErr = s.stdinBuffer.Read(bufR)
if s.bufErr != nil {
if s.bufErr == io.ErrClosedPipe {
break
}
}
s.Lock() s.Lock()
s.buf = append(s.buf, bufR[:n]...) s.buf = append(s.buf, bufR[:n]...)
s.Unlock() s.Unlock()
@ -184,7 +187,11 @@ func (s *FillableStdin) Read(p []byte) (n int, err error) {
return n, cerr return n, cerr
} }
s.Unlock() s.Unlock()
n, err = s.stdin.Read(p)
return s.stdin.Read(p) return n, err
}
func (s *FillableStdin) Close() error {
s.stdinBuffer.Close()
return nil
} }