No need to store most channels on self

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

View File

@ -41,11 +41,7 @@ type Loop struct {
exit_code int exit_code int
timers []*timer timers []*timer
timer_id_counter, write_msg_id_counter IdType timer_id_counter, write_msg_id_counter IdType
tty_read_channel chan []byte wakeup_channel chan byte
tty_write_channel chan *write_msg
write_done_channel chan IdType
err_channel chan error
tty_writing_done_channel, tty_reading_done_channel, wakeup_channel chan byte
pending_writes []*write_msg pending_writes []*write_msg
// Callbacks // Callbacks
@ -151,7 +147,7 @@ func (self *Loop) WakeupMainThread() {
func (self *Loop) QueueWriteString(data string) IdType { func (self *Loop) QueueWriteString(data string) IdType {
self.write_msg_id_counter++ self.write_msg_id_counter++
msg := write_msg{str: data, id: self.write_msg_id_counter} msg := write_msg{str: data, id: self.write_msg_id_counter}
self.queue_write_to_tty(&msg) self.add_write_to_pending_queue(&msg)
return msg.id return msg.id
} }
@ -160,7 +156,7 @@ func (self *Loop) QueueWriteString(data string) IdType {
func (self *Loop) QueueWriteBytesDangerous(data []byte) IdType { func (self *Loop) QueueWriteBytesDangerous(data []byte) IdType {
self.write_msg_id_counter++ self.write_msg_id_counter++
msg := write_msg{bytes: data, id: self.write_msg_id_counter} msg := write_msg{bytes: data, id: self.write_msg_id_counter}
self.queue_write_to_tty(&msg) self.add_write_to_pending_queue(&msg)
return msg.id return msg.id
} }

View File

@ -193,14 +193,14 @@ func (self *Loop) run() (err error) {
} }
self.keep_going = true self.keep_going = true
self.tty_read_channel = make(chan []byte) tty_read_channel := make(chan []byte)
self.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
self.write_done_channel = make(chan IdType) write_done_channel := make(chan IdType)
self.tty_writing_done_channel = make(chan byte) tty_writing_done_channel := make(chan byte)
self.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)
self.err_channel = make(chan error, 8) err_channel := make(chan error, 8)
self.death_signal = SIGNULL self.death_signal = SIGNULL
self.escape_code_parser.Reset() self.escape_code_parser.Reset()
self.exit_code = 0 self.exit_code = 0
@ -224,22 +224,22 @@ func (self *Loop) run() (err error) {
defer func() { defer func() {
// notify tty reader that we are shutting down // notify tty reader that we are shutting down
r_w.Close() r_w.Close()
close(self.tty_reading_done_channel) close(tty_reading_done_channel)
if finalizer != "" { if finalizer != "" {
self.QueueWriteString(finalizer) self.QueueWriteString(finalizer)
} }
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, self.tty_write_channel, self.tty_writing_done_channel, self.pending_writes, 2*time.Second) flush_writer(w_w, tty_write_channel, tty_writing_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 = <-self.tty_read_channel { for more := true; more; _, more = <-tty_read_channel {
} }
}() }()
go write_to_tty(w_r, self.controlling_term, self.tty_write_channel, self.err_channel, self.write_done_channel, self.tty_writing_done_channel) go write_to_tty(w_r, self.controlling_term, tty_write_channel, err_channel, write_done_channel, tty_writing_done_channel)
go read_from_tty(r_r, self.controlling_term, self.tty_read_channel, self.err_channel, self.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 {
finalizer, err = self.OnInitialize() finalizer, err = self.OnInitialize()
@ -249,7 +249,7 @@ func (self *Loop) run() (err error) {
} }
for self.keep_going { for self.keep_going {
self.queue_write_to_tty(nil) self.flush_pending_writes(tty_write_channel)
timeout_chan := no_timeout_channel timeout_chan := no_timeout_channel
if len(self.timers) > 0 { if len(self.timers) > 0 {
now := time.Now() now := time.Now()
@ -269,8 +269,8 @@ func (self *Loop) run() (err error) {
for len(self.wakeup_channel) > 0 { for len(self.wakeup_channel) > 0 {
<-self.wakeup_channel <-self.wakeup_channel
} }
case msg_id := <-self.write_done_channel: case msg_id := <-write_done_channel:
self.queue_write_to_tty(nil) self.flush_pending_writes(tty_write_channel)
if self.OnWriteComplete != nil { if self.OnWriteComplete != nil {
err = self.OnWriteComplete(msg_id) err = self.OnWriteComplete(msg_id)
if err != nil { if err != nil {
@ -282,7 +282,7 @@ func (self *Loop) run() (err error) {
if err != nil { if err != nil {
return err return err
} }
case input_data, more := <-self.tty_read_channel: case input_data, more := <-tty_read_channel:
if !more { if !more {
return io.EOF return io.EOF
} }

View File

@ -57,27 +57,19 @@ func writestring_ignoring_temporary_errors(f *tty.Term, buf string) (int, error)
return n, err return n, err
} }
func (self *Loop) queue_write_to_tty(data *write_msg) { func (self *Loop) flush_pending_writes(tty_write_channel chan<- *write_msg) {
for len(self.pending_writes) > 0 { for len(self.pending_writes) > 0 {
select { select {
case self.tty_write_channel <- self.pending_writes[0]: case tty_write_channel <- self.pending_writes[0]:
n := copy(self.pending_writes, self.pending_writes[1:]) n := copy(self.pending_writes, self.pending_writes[1:])
self.pending_writes = self.pending_writes[:n] self.pending_writes = self.pending_writes[:n]
default: }
if data != nil { }
}
func (self *Loop) add_write_to_pending_queue(data *write_msg) {
self.pending_writes = append(self.pending_writes, data) self.pending_writes = append(self.pending_writes, data)
} }
return
}
}
if data != nil {
select {
case self.tty_write_channel <- data:
default:
self.pending_writes = append(self.pending_writes, data)
}
}
}
func create_write_dispatcher(msg *write_msg) *write_dispatcher { func create_write_dispatcher(msg *write_msg) *write_dispatcher {
self := write_dispatcher{str: msg.str, bytes: msg.bytes, is_string: msg.bytes == nil} self := write_dispatcher{str: msg.str, bytes: msg.bytes, is_string: msg.bytes == nil}