Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One-shot *level*-triggered epoll(): Does EPOLLONESHOT imply EPOLLET?

Is it possible to use epoll in one-shot level-triggered mode?
I couldn't find any information on it when I searched; it seems everyone uses edge-triggered mode.

like image 745
user541686 Avatar asked Aug 26 '16 19:08

user541686


2 Answers

When the EPOLLONESHOT flag is selected and you have pulled an event for a socket, then the socket won't get removed from epoll as many think but its events get disabled. You can enable them again using epoll_ctl / EPOLL_CTL_MOD.

An example case when the EPOLLONESHOT behavior comes handy is when you've read the available data from a socket into a buffer. That buffer would be emptied independently, but until it isn't empty, you have to disable the socket events, even if the socket has additional data. Then after the buffer got used and emptied, you can re-enable the socket.

The difference between the edge- and level-triggered "one shot" behaviors come only when you re-enable the socket. An example:

  1. The socket receives 7K data (for now it's stored in a kernel buffer)
  2. You wait for an input event, then the socket events get disabled due to the EPOLLONESHOT.
  3. You read 4K into an application level buffer.
  4. Later the application buffer gets used and emptied. You re-enable the socket with epoll_ctl / EPOLL_CTL_MOD.

Level-triggered EPOLLONESHOT:

  1. Since 3K data is still present in the kernel buffers, the event is triggered again.

Edge-triggered EPOLLONESHOT:

  1. It won't trigger an event again for the available data. You must test it by reading, and waiting for EAGAIN / EWOULDBLOCK.
like image 97
Crouching Kitten Avatar answered Sep 23 '22 01:09

Crouching Kitten


If you want epoll to stop listening on a socket the you should use EPOLLONESHOT. If you do use EPOLLONESHOT then you will have to add the socket back to epoll after epoll signals on that socket. Thus EPOLLONESHOT is not EPOLLET. You can use EPOLLONESHOT without EPOLLET, but it might not be efficient. If you use both the flags, then you will have to make use of non blocking sockets and add a socket to epoll only once recv and send return with an EAGAIN error. Please refer to man page for details.

like image 45
Sweekrut Joshi Avatar answered Sep 23 '22 01:09

Sweekrut Joshi