On Sat, Dec 21, 2019 at 7:09 AM Daniel Eloff <dan....@gmail.com> wrote:
>
> Digging a little, it seems Go net poller uses edge triggered epoll on Linux. One of the harder considerations about using edge-triggered epoll is you have to read()/write() until EGAIN, otherwise you will not receive another read/write event for the socket when you call epoll_wait.
>
> My question is, how does this work if you use the new(ish) RawConn interface? It's not stated that there are any requirements to read/write until EGAIN, just that it's expected that the programmer calls read/write (presumably through syscall.Read/Write.) What happens if you return e.g. done=true without calling read/write at all? This may be useful if you just want to wait until data is available for reading without tying up a buffer in a read call, e.g. if you have a long-lived but idle connection like a websocket, or you're waiting for follow-up requests on an http keep-alive connection, or http2 connection as in grpc.
>
> I went through the poller code, but did not manage to figure out the answer.
As far as I can see there is no problem if the function returns true
without doing a read. In the normal file I/O case, a Read will never
wait for the poller unless the system call returns EAGAIN. That is, a
call to the Read method does not start by waiting for the poller to
report that the descriptor is ready. It always calls the read system
call, and only if read returns EAGAIN does it wait for the poller.
However, I think there might be a potential problem if the RawConn
Read method is called with a function that returns false after making
a read call that does not return EAGAIN. In that case the net package
will wait for the poller, but there might be nothing that triggers it.
Come to think of it, you said return done=true but you probably meant
return done=false. You're right: I don't think that will work. I
think that as the docs say "f is expected to try to read from the file
descriptor."