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?
In edge-triggered mode, a call to epoll_wait will return only when a new event is enqueued with the epoll object, while in level-triggered mode, epoll_wait will return as long as the condition holds.
epoll monitors I/O events for multiple file descriptors. epoll supports edge trigger (ET) or level trigger (LT), which waits for I/O events via epoll_wait and blocks the calling thread if no events are currently available. select and poll only support LT working mode, and the default working mode of epoll is LT mode.
epoll_ctl() is a control function that allows us to add descriptors to a watch set, remove descriptors from a watch set, or reconfigure file descriptors already in the watch set. epoll_wait() waits for I/O events on the watch set, blocking the calling thread until one or more events are detected.
epoll stands for event poll and is a Linux specific construct. It allows for a process to monitor multiple file descriptors and get notifications when I/O is possible on them. It allows for both edge-triggered as well as level-triggered notifications.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With