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 <-d.closeChannel: if !d.WriterClosed { d.WriterClosed = true close(d.writerChannel) } log.Println("~Writer") return default: } */ select { /* case <-d.closeChannel: // Not safe from data races -- not synced if !d.WriterClosed { d.WriterClosed = true close(d.writerChannel) } // close(d.writerChannel) log.Println("~Writer") return */ 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 // close(d.writerChannel) } d.writerMutex.Unlock() /* if !d.Disconnect() { // d.Disconnected = true // atomic.StoreInt32(&d.Disconnected, 1) // if !ok, the channel is already closed... // close(d.writerChannel) } */ log.Println("~Writer") return // d.closeChannel <- true // continue } 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 == "" { // Close Channel /* if !d.WriterClosed { d.WriterClosed = true close(d.writerChannel) } */ /* d.writerMutex.Lock() if !d.WriterClosed { d.WriterClosed = true close(d.writerChannel) // } */ Closed = true // d.SafeWriterClose() // log.Println("~Writer") // return 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() //d.SafeWriterClose() /* d.WriterClosed = true close(d.writerChannel) */ /* if !d.Disconnect() { // d.Disconnected = true // atomic.StoreInt32(&d.Disconnected, 1) close(d.writerChannel) } */ // log.Println("~Writer") // return } } } } } /* func Writer(handle int, writerChannel *chan string) { for output := range *writerChannel { buffer := []byte(output) n, err := syscall.Write(handle, buffer) if (err != nil) || (n != len(buffer)) { close(*writerChannel) break } } } */