write_linux.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package door
  2. import (
  3. "log"
  4. "strings"
  5. "syscall"
  6. )
  7. // https://go101.org/article/channel-closing.html
  8. func Writer(d *Door) {
  9. var handle int = d.Config.Comm_handle
  10. log.Println("Writer")
  11. defer d.wg.Done()
  12. var Closed bool = false
  13. for {
  14. select {
  15. case output, ok := <-d.writerChannel:
  16. if !ok {
  17. log.Println("closeChannel")
  18. d.writerMutex.Lock()
  19. if !d.WriterClosed {
  20. // Safe from data races, writerChannel unbuffered
  21. d.WriterClosed = true
  22. }
  23. d.writerMutex.Unlock()
  24. log.Println("~Writer")
  25. return
  26. } else {
  27. // log.Println("output")
  28. /* Handle cases where we're updating a portion of the screen.
  29. When we SavePos, also save/restore the last color set.
  30. */
  31. if output == "" {
  32. Closed = true
  33. continue
  34. }
  35. if Closed {
  36. log.Println("ignoring write output.")
  37. continue
  38. }
  39. if strings.HasSuffix(output, RestorePos) {
  40. output += Color(d.LastColor...)
  41. } else {
  42. d.UpdateLastColor(output, &d.LastColor)
  43. }
  44. // log.Println("write output")
  45. buffer := []byte(output)
  46. n, err := syscall.Write(handle, buffer)
  47. if (err != nil) || (n != len(buffer)) {
  48. log.Println("closeChannel")
  49. Closed = true
  50. d.writerMutex.Lock()
  51. if !d.WriterClosed {
  52. d.WriterClosed = true
  53. // close(d.writerChannel)
  54. }
  55. d.writerMutex.Unlock()
  56. }
  57. }
  58. }
  59. }
  60. }