Use one less channel

This commit is contained in:
Kovid Goyal 2022-08-26 15:55:08 +05:30
parent bf35817d73
commit a75d59643c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 26 additions and 12 deletions

View File

@ -196,7 +196,6 @@ func (self *Loop) run() (err error) {
tty_read_channel := make(chan []byte) 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 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) write_done_channel := make(chan IdType)
tty_writing_done_channel := make(chan byte)
tty_reading_done_channel := make(chan byte) tty_reading_done_channel := make(chan byte)
self.wakeup_channel = make(chan byte, 256) self.wakeup_channel = make(chan byte, 256)
self.pending_writes = make([]*write_msg, 0, 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()) 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 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 self.pending_writes = nil
// wait for tty reader to exit cleanly // wait for tty reader to exit cleanly
for more := true; more; _, more = <-tty_read_channel { 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) go read_from_tty(r_r, self.controlling_term, tty_read_channel, err_channel, tty_reading_done_channel)
if self.OnInitialize != nil { if self.OnInitialize != nil {

View File

@ -100,12 +100,12 @@ func (self *write_dispatcher) slice(n int) {
func write_to_tty( func write_to_tty(
pipe_r *os.File, term *tty.Term, 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 keep_going := true
defer func() { defer func() {
pipe_r.Close() pipe_r.Close()
close(completed_channel) close(write_done_channel)
}() }()
selector := utils.CreateSelect(2) selector := utils.CreateSelect(2)
pipe_fd := int(pipe_r.Fd()) 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 writer_quit := false
defer func() { defer func() {
if tty_write_channel != nil { 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() pipe_w.Close()
if !writer_quit { if !writer_quit {
<-tty_writing_done_channel for {
_, more := <-write_done_channel
if !more {
writer_quit = true writer_quit = true
break
}
}
} }
}() }()
deadline := time.Now().Add(timeout) 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 { select {
case <-time.After(timeout): case <-time.After(timeout):
return return
case _, more := <-write_done_channel:
if !more {
writer_quit = true
break
}
case tty_write_channel <- pending_writes[0]: case tty_write_channel <- pending_writes[0]:
pending_writes = pending_writes[1:] 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 { if timeout <= 0 {
return return
} }
for !writer_quit {
select { select {
case <-tty_writing_done_channel: case _, more := <-write_done_channel:
if !more {
writer_quit = true writer_quit = true
}
case <-time.After(timeout): case <-time.After(timeout):
break
}
} }
return return
} }