write_linux.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package door
  2. import (
  3. "log"
  4. "strings"
  5. "syscall"
  6. "sync/atomic"
  7. )
  8. // https://go101.org/article/channel-closing.html
  9. // This will get renamed back to Writer, once I get
  10. // it working...
  11. func Writer2(handle int, d *Door) {
  12. log.Println("Writer2")
  13. defer d.wg.Done()
  14. for {
  15. select {
  16. case <- d.closeChannel:
  17. close(d.writerChannel)
  18. log.Println("~Writer2")
  19. return
  20. default:
  21. }
  22. select {
  23. case <- d.closeChannel:
  24. close(d.writerChannel)
  25. log.Println("~Writer2")
  26. return
  27. case output, ok := <-d.writerChannel:
  28. if !ok {
  29. log.Println("closeChannel")
  30. if ! d.Disconnect() {
  31. // d.Disconnected = true
  32. atomic.StoreInt32(&d.Disconnected, 1)
  33. // if !ok, the channel is already closed...
  34. // close(d.writerChannel)
  35. }
  36. log.Println("~Writer2")
  37. return
  38. // d.closeChannel <- true
  39. // continue
  40. } else {
  41. // log.Println("output")
  42. /* Handle cases where we're updating a portion of the screen.
  43. When we SavePos, also save/restore the last color set.
  44. */
  45. if strings.HasSuffix(output, RestorePos) {
  46. output += Color(d.LastColor...)
  47. } else {
  48. d.UpdateLastColor(output, &d.LastColor)
  49. }
  50. // log.Println("write output")
  51. buffer := []byte(output)
  52. n, err := syscall.Write(handle, buffer)
  53. if (err != nil) || (n != len(buffer)) {
  54. log.Println("closeChannel")
  55. if ! d.Disconnect() {
  56. // d.Disconnected = true
  57. atomic.StoreInt32(&d.Disconnected, 1)
  58. close(d.writerChannel)
  59. }
  60. log.Println("~Writer2")
  61. return
  62. }
  63. }
  64. }
  65. }
  66. }
  67. func Writer(handle int, writerChannel *chan string) {
  68. for output := range *writerChannel {
  69. buffer := []byte(output)
  70. n, err := syscall.Write(handle, buffer)
  71. if (err != nil) || (n != len(buffer)) {
  72. close(*writerChannel)
  73. break
  74. }
  75. }
  76. }