关于使用Epoll Edge Triggered时re-arming EPOLL的时机问题及相关问题

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

我对使用 Edge Triggered 和 EPOLLONESHOT 时的 EPOLL 有一些疑问。

下面列出了简化的语句序列。实际上多个文件由一个Epoll Fd监控,一个集合通过特定的线程管理。使用的变量名称不言而喻,当然是设置的。为简洁起见省略该部分:

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 ***/

}

问题:

  1. 使用EPOLLONESHOT时,什么时候REARMED EPOLL?事件接收后还是事件处理后?

  2. 初级。写入或读取时,我们会跟踪数据点 written/read 直到返回 EAGAIN 或部分 read/written? Yes/No.

  3. 最初没有设置 EPOLLOUT。写的时候,写returnsEAGAIN的时候,我们把EPOLLOUT加到事件中 被监控。 Yes/No?

  4. 当一个FD再次触发EPOLLOUT时,我们从上次接收到EAGAIN的点继续写入 一直这样做,直到我们再次获得 EAGAIN。然后我们重新武装。 Yes/No?

  5. 如果我们只读了一部分,不REARM,新数据会不断到达,但不会触发任何事件。 所以,如果我们部分读取,我们需要跟踪它,而不是仅仅依靠事件处理程序来进行读取处理。对吧?

我不能全部回答,但我可以尝试回答一些。

  1. 初级。写入或读取时,我们会跟踪数据点 written/read 直到返回 EAGAIN 或部分 read/written? Yes/No.
    • 对于read/recv:您应该处理以下所有情况
      1. 如果您 read/recv EAGAIN 或 EWOULDBLOCK。这表明 read/recv 没有任何剩余,您应该从接收循环中中断。
      2. 您收到 0 个字节。这表示对方已经没有连接了
      3. 您收到 0 > 个字节。您成功 read/recv 数据,应该再次 read/recv。
    • 您不一定需要跟踪数据,只需确保处理上述 3 种情况即可。
  2. 最初没有设置 EPOLLOUT。写的时候,写returnsEAGAIN的时候,我们把EPOLLOUT加入到要监听的事件中。 Yes/No?

    • 是的...我相信在最初设置 EPOLLOUT 的情况下,send() FD 上应该会出现与您在问题中描述的相同的行为...假设您只需写入 FD无论事件通知如何,只有在收到 EAGAIN/EWOULDBOCK 错误后才会停止。