diff --git a/tools/tui/loop/run.go b/tools/tui/loop/run.go index 9766d3e93..4ab769d1a 100644 --- a/tools/tui/loop/run.go +++ b/tools/tui/loop/run.go @@ -196,7 +196,6 @@ func (self *Loop) run() (err error) { tty_read_channel := make(chan []byte) tty_write_channel := make(chan *write_msg, 1) // buffered so there is no race between initial queueing and startup of writer thread write_done_channel := make(chan IdType) - tty_writing_done_channel := make(chan byte) tty_reading_done_channel := make(chan byte) self.wakeup_channel = make(chan byte, 256) self.pending_writes = make([]*write_msg, 0, 256) @@ -231,14 +230,14 @@ func (self *Loop) run() (err error) { } self.QueueWriteBytesDangerous(self.terminal_options.ResetStateEscapeCodes()) // flush queued data and wait for it to be written for a timeout, then wait for writer to shutdown - flush_writer(w_w, tty_write_channel, tty_writing_done_channel, self.pending_writes, 2*time.Second) + flush_writer(w_w, tty_write_channel, write_done_channel, self.pending_writes, 2*time.Second) self.pending_writes = nil // wait for tty reader to exit cleanly for more := true; more; _, more = <-tty_read_channel { } }() - go write_to_tty(w_r, self.controlling_term, tty_write_channel, err_channel, write_done_channel, tty_writing_done_channel) + go write_to_tty(w_r, self.controlling_term, tty_write_channel, err_channel, write_done_channel) go read_from_tty(r_r, self.controlling_term, tty_read_channel, err_channel, tty_reading_done_channel) if self.OnInitialize != nil { diff --git a/tools/tui/loop/write.go b/tools/tui/loop/write.go index 3bf53ae8a..951132b74 100644 --- a/tools/tui/loop/write.go +++ b/tools/tui/loop/write.go @@ -100,12 +100,12 @@ func (self *write_dispatcher) slice(n int) { func write_to_tty( pipe_r *os.File, term *tty.Term, - job_channel <-chan *write_msg, err_channel chan<- error, write_done_channel chan<- IdType, completed_channel chan<- byte, + job_channel <-chan *write_msg, err_channel chan<- error, write_done_channel chan<- IdType, ) { keep_going := true defer func() { pipe_r.Close() - close(completed_channel) + close(write_done_channel) }() selector := utils.CreateSelect(2) pipe_fd := int(pipe_r.Fd()) @@ -162,7 +162,7 @@ func write_to_tty( } } -func flush_writer(pipe_w *os.File, tty_write_channel chan<- *write_msg, tty_writing_done_channel <-chan byte, pending_writes []*write_msg, timeout time.Duration) { +func flush_writer(pipe_w *os.File, tty_write_channel chan<- *write_msg, write_done_channel <-chan IdType, pending_writes []*write_msg, timeout time.Duration) { writer_quit := false defer func() { if tty_write_channel != nil { @@ -171,8 +171,13 @@ func flush_writer(pipe_w *os.File, tty_write_channel chan<- *write_msg, tty_writ } pipe_w.Close() if !writer_quit { - <-tty_writing_done_channel - writer_quit = true + for { + _, more := <-write_done_channel + if !more { + writer_quit = true + break + } + } } }() deadline := time.Now().Add(timeout) @@ -184,6 +189,11 @@ func flush_writer(pipe_w *os.File, tty_write_channel chan<- *write_msg, tty_writ select { case <-time.After(timeout): return + case _, more := <-write_done_channel: + if !more { + writer_quit = true + break + } case tty_write_channel <- pending_writes[0]: pending_writes = pending_writes[1:] } @@ -194,10 +204,15 @@ func flush_writer(pipe_w *os.File, tty_write_channel chan<- *write_msg, tty_writ if timeout <= 0 { return } - select { - case <-tty_writing_done_channel: - writer_quit = true - case <-time.After(timeout): + for !writer_quit { + select { + case _, more := <-write_done_channel: + if !more { + writer_quit = true + } + case <-time.After(timeout): + break + } } return }