Hi, I would like to call syscall.Read() with a timeout. Coming from C, my first idea was to use syscall.Select(), which should work fine. However, I came across this answer from 2014 by Ian Lance Taylor to a similar question (https://groups.google.com/d/msg/golang-nuts/al-6_QFgYaM/UkCqyCQVq_0J):
The usual approach in Go is to use a simple goroutine that reads from the > file and writes to a channel. Then you can use the select statement to > check the channel when appropriate. It's unusual to want to use the poll > or select system calls since the language gives you other ways to do the > same thing. I tried it, but I find it harder than it sounds. Here's my pseudo code: data := make(chan byte) fd := some file descriptor go func() { buf = make([]byte, 1) for { n, err = syscall.Read(fd, buf) if err != nil { close(data) return } data <- buf[0] } } select { case b := <- data: // do something with b case <- timeout: syscall.Close(fd) } The idea is obvious: When the timeout is reached, fd is closed, which interrupts the blocking syscall.Read(), which terminates the goroutine. However, there is a race condition: If the timeout is reached immediately after a successful syscall.Read(), the line 'data <- buf[0]' will block forever, as no consumer reads data anymore. Adding capacity to the data channel doesn't help, because theoretically the loop might repeat multiple times between the timeout is received and fd is actually closed. How can I refactor this pseudo code to get rid of the race condition? How can I implement a syscall.Read() with timeout using a goroutine, channel, and golang's select statement? Thanks for your help Fabian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.