package door import ( "log" "strings" "syscall" ) // https://go101.org/article/channel-closing.html func Writer(d *Door) { var handle int = d.Config.Comm_handle log.Println("Writer") defer d.wg.Done() var Closed bool = false for { select { case output, ok := <-d.writerChannel: if !ok { log.Println("closeChannel") d.writerMutex.Lock() if !d.WriterClosed { // Safe from data races, writerChannel unbuffered d.WriterClosed = true } d.writerMutex.Unlock() log.Println("~Writer") return } else { // log.Println("output") /* Handle cases where we're updating a portion of the screen. When we SavePos, also save/restore the last color set. */ if output == "" { Closed = true continue } if Closed { log.Println("ignoring write output.") continue } if strings.HasSuffix(output, RestorePos) { output += Color(d.LastColor...) } else { d.UpdateLastColor(output, &d.LastColor) } // log.Println("write output") buffer := []byte(output) n, err := syscall.Write(handle, buffer) if (err != nil) || (n != len(buffer)) { log.Println("closeChannel") Closed = true d.writerMutex.Lock() if !d.WriterClosed { d.WriterClosed = true // close(d.writerChannel) } d.writerMutex.Unlock() } } } } }