From f6d7a1f6fbf35bbf9beb80dc63c56a29dcfb759f Mon Sep 17 00:00:00 2001 From: soopsio <32614138+soopsio@users.noreply.github.com> Date: Fri, 8 Dec 2017 09:17:16 +0800 Subject: [PATCH] Fix ioloop groutine leaks bug. (#136) * Fix ioloop groutine leaks bug. * fix func (o *Operation) ioloop() L:125 hangs --- .gitignore | 1 + operation.go | 2 +- readline.go | 3 ++- remote.go | 3 ++- std.go | 21 ++++++++++++++------- 5 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a3062be --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/* diff --git a/operation.go b/operation.go index e2ae6ba..4c31624 100644 --- a/operation.go +++ b/operation.go @@ -72,7 +72,7 @@ func NewOperation(t *Terminal, cfg *Config) *Operation { t: t, buf: NewRuneBuffer(t, cfg.Prompt, cfg, width), outchan: make(chan []rune), - errchan: make(chan error), + errchan: make(chan error, 1), } op.w = op.buf.w op.SetConfig(cfg) diff --git a/readline.go b/readline.go index 585d94b..0e7aca0 100644 --- a/readline.go +++ b/readline.go @@ -54,7 +54,7 @@ type Config struct { FuncGetWidth func() int - Stdin io.Reader + Stdin io.ReadCloser StdinWriter io.Writer Stdout io.Writer Stderr io.Writer @@ -274,6 +274,7 @@ func (i *Instance) Close() error { if err := i.Terminal.Close(); err != nil { return err } + i.Config.Stdin.Close() i.Operation.Close() return nil } diff --git a/remote.go b/remote.go index db77ae8..74dbf56 100644 --- a/remote.go +++ b/remote.go @@ -189,11 +189,12 @@ loop: } } -func (r *RemoteSvr) Close() { +func (r *RemoteSvr) Close() error { if atomic.CompareAndSwapInt32(&r.closed, 0, 1) { close(r.stopChan) r.conn.Close() } + return nil } func (r *RemoteSvr) readLoop(buf *bufio.Reader) { diff --git a/std.go b/std.go index 0fd90ff..61d44b7 100644 --- a/std.go +++ b/std.go @@ -137,14 +137,13 @@ func (c *CancelableStdin) Close() error { type FillableStdin struct { sync.Mutex stdin io.Reader - stdinBuffer io.Reader + stdinBuffer io.ReadCloser buf []byte bufErr error } // 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() s := &FillableStdin{ stdinBuffer: r, @@ -152,7 +151,6 @@ func NewFillableStdin(stdin io.Reader) (io.Reader, io.Writer) { } s.ioloop() return s, w - } func (s *FillableStdin) ioloop() { @@ -161,6 +159,11 @@ func (s *FillableStdin) ioloop() { bufR := make([]byte, 100) var n int n, s.bufErr = s.stdinBuffer.Read(bufR) + if s.bufErr != nil { + if s.bufErr == io.ErrClosedPipe { + break + } + } s.Lock() s.buf = append(s.buf, bufR[:n]...) s.Unlock() @@ -184,7 +187,11 @@ func (s *FillableStdin) Read(p []byte) (n int, err error) { return n, cerr } s.Unlock() - - return s.stdin.Read(p) - + n, err = s.stdin.Read(p) + return n, err +} + +func (s *FillableStdin) Close() error { + s.stdinBuffer.Close() + return nil }