From e06700a8ff17afd011891f52e148da8dcf84ee2f Mon Sep 17 00:00:00 2001 From: John Brooks Date: Sun, 23 Oct 2016 08:22:52 -0700 Subject: [PATCH] Fix a race condition in Refresh and wrapWriter These functions would bypass calling RuneBuffer.Refresh when Terminal.IsReading(), but this leads to a race condition when another goroutine is just beginning to read. The result is that the prompt is not erased or rewritten in some cases. RuneBuffer.Refresh protects this with a mutex, and looks safe to call even when !IsReading(), so removing these redundant checks seems sufficient. The tested scenario is to have goroutine A calling Readline in a loop and handling commands, and goroutine B periodically printing to Instance.Stdout(). If the print in B is timed just before A calls Readline, the printed line is displayed after the prompt and the prompt is not reprinted until the next input. --- operation.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/operation.go b/operation.go index 2c93561..497e6c6 100644 --- a/operation.go +++ b/operation.go @@ -43,10 +43,6 @@ type wrapWriter struct { } func (w *wrapWriter) Write(b []byte) (int, error) { - if !w.t.IsReading() { - return w.target.Write(b) - } - var ( n int err error @@ -478,9 +474,7 @@ func (o *Operation) SaveHistory(content string) error { } func (o *Operation) Refresh() { - if o.t.IsReading() { - o.buf.Refresh(nil) - } + o.buf.Refresh(nil) } func (o *Operation) Clean() {