package door import ( "log" "syscall" "sync/atomic" ) func Reader2(handle int, d *Door) { // I don't need the select anymore. Let the read block. // defer d.wg.Done() defer func() { log.Printf("~Reader2\n") d.wg.Done() }() defer func() { if err := recover(); err != nil { log.Printf("Reader: %#v\n", err) } }() buffer := make([]byte, 1) for { read, err := syscall.Read(handle, buffer) if err != nil { log.Printf("Reader ERR: %#v\n", err) close(d.readerChannel) if ! d.Disconnect() { log.Println("Reader close writerChannel") // d.Disconnected = true atomic.StoreInt32(&d.Disconnected, 1) d.closeChannel <- true // close(d.writerChannel) return } // break return } if read == 1 { d.readerChannel <- buffer[0] } else { log.Printf("READ FAILED %d\n", read) close(d.readerChannel) if ! d.Disconnect() { log.Println("Reader close writerChannel") // d.Disconnected = true atomic.StoreInt32(&d.Disconnected, 1) d.closeChannel <- true //close(d.writerChannel) return } // break return } } } func Reader(handle int, readerChannel *chan byte) { // I don't need the select anymore. Let the read block. defer func() { if err := recover(); err != nil { log.Printf("Reader: %#v\n", err) } }() buffer := make([]byte, 1) for { // blocking read in go routine // why doesn't this end when I close the handle? read, err := syscall.Read(handle, buffer) if err != nil { log.Printf("Reader ERR: %#v\n", err) close(*readerChannel) break } if read == 1 { *readerChannel <- buffer[0] } else { log.Printf("READ FAILED %d\n", read) close(*readerChannel) break } } } func CloseReader(handle int) { defer func() { if err := recover(); err != nil { log.Printf("CloseReader: %#v\n", err) } }() syscall.Close(handle) }