epollepollet

Using edge triggered epoll, should I loop over send?


I'm using epoll to write a media server. The fds are all set to non-blocking and I'm using edge-triggered events. I know for EPOLLIN I need to loop over reading the fd until EAGAIN is returned. But what about writing?

When I want to write I queue the data and set EPOLLOUT|EPOLLIN|EPOLLET on the fd. When the EPOLLOUT event occurs I write the whole queued buffer in one shot:

n = send ( fd, buf, buf_len, MSG_NOSIGNAL );

If n > 0 && n < buf_len I just reset EPOLLOUT and return. I don't see the sense in looping over send (which I think the man page for epoll implies). It seems like send has indicated it has just taken in all it can and will return EAGAIN if called immediately.

Is eliminating a system call here the most efficient route?


Solution

  • epoll man page says:

    For stream-oriented files (e.g., pipe, FIFO, stream socket), the condition that the read/write I/O space is exhausted can also be detected by checking the amount of data read from / written to the target file descriptor. For example, if you call read(2) by asking to read a certain amount of data and read(2) returns a lower number of bytes, you can be sure of having exhausted the read I/O space for the file descriptor. The same is true when writing using write(2). (Avoid this latter technique if you cannot guarantee that the monitored file descriptor always refers to a stream-oriented file.)