Search code examples
epollepollet

Question on the timing of re-arming EPOLL and related questions when using Epoll Edge Triggered


I have some questions on EPOLL when using Edge Triggered and with EPOLLONESHOT.

The simplified sequence of statements are listed below. Actually multiple files are monitored by an Epoll Fd and a set is managed through a specific thread. The variable names used speak for themselves and are, of course, set. That part is omitted for the sake of brevity:

1.  Create epollFd
  epollFd = epoll_create1(EPOLL_CLOEXEC);

2.  Create events to monitor
  epollEventParam.events  = EPOLLIN |  EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT;


3.  Add the FD to monitor and the events
  epoll_ctl(epollFd, EPOLL_CTL_ADD, socketFd, &epollEventParam);

4.  While loop with epoll_wait
   while (1) {

     noFdsEvented = epoll_wait(epollFd, epollEventsReported, maxEvents, -1);


     /***************** REARM Here or after processing the events? ******/
     epoll_ctl(epollFd, EPOLL_CTL_MOD, (int)epollEventsReported[i].data.fd, &epollEventParam);


     /** if EPOLLIN, read until read returns EAGIN  ***/
     //Relevant code to read...
     //After EAGAIN is returned, REARM Here instead of doing so earlier (above)?

     /** if EPOLLOUT, write until write returns EAGIN  ***/
     //Relevant code to write...
     //After EAGAIN is returned, REARM Here instead of doing so earlier (above)?

     /*** If other events... process accordingly ***/

}

QUESTIONS:

  1. When EPOLLONESHOT is used, when should EPOLL be REARMED? After the event is received or after the event is processed?

  2. Elementary. When writing or reading, we keep track of the data point written/read until EAGAIN was returned or if partially read/written? Yes/No.

  3. Initially EPOLLOUT is not set. When writing, when write returns EAGAIN, we add EPOLLOUT to the event to be monitored. Yes/No?

  4. When EPOLLOUT is triggered again for an FD, we continue writing from the point EAGAIN was last received and do so until we get EAGAIN again. THen we REARM. Yes/No?

  5. If we read partially and do not REARM, new data will continue to arrive but no event will be triggered. So, if we read partially, we need to keep track of it and not rely only on the event handler to do read processing. Right?


Solution

  • I can't answer all of them, but I can try to answer a few.

    1. Elementary. When writing or reading, we keep track of the data point written/read until EAGAIN was returned or if partially read/written? Yes/No.
      • For read/recv: you should handle all of the following scenarios
        1. If you read/recv EAGAIN or EWOULDBLOCK. This indicates that there is nothing left to read/recv and you should break from the receive loop.
        2. You receive 0 bytes. This indicates that the other side is no longer connected
        3. You receive 0 > bytes. You successfully read/recv data and should read/recv again.
      • You dont necessarily need to keep track of the data as opposed to just ensure you handle the above 3 scenarios.
    2. Initially EPOLLOUT is not set. When writing, when write returns EAGAIN, we add EPOLLOUT to the event to be monitored. Yes/No?

      • Yes...I believe that in the instance where EPOLLOUT is initially set, the same behaviour on the send() FD should occur as you described in the question...given that you will simply write to the FD regardless of the event notification and only stop once you get an EAGAIN/EWOULDBOCK error.