@@ -215,10 +215,33 @@ func (e *MultiEventLoop) doRead(c *Conn, rbuf []byte) {
215215 handleData (c , & e .options , rbuf [:n ])
216216 }
217217
218- if e .options .triggerType == core .TriggerTypeLevel {
219- if n < len (rbuf ) {
220- break
221- }
218+ // https://man7.org/linux/man-pages/man7/epoll.7.html
219+ // Do I need to continuously read/write a file descriptor until
220+ // EAGAIN when using the EPOLLET flag (edge-triggered behavior)?
221+
222+ // Receiving an event from epoll_wait(2) should suggest to you
223+ // that such file descriptor is ready for the requested I/O
224+ // operation. You must consider it ready until the next
225+ // (nonblocking) read/write yields EAGAIN. When and how you will
226+ // use the file descriptor is entirely up to you.
227+
228+ // For packet/token-oriented files (e.g., datagram socket,
229+ // terminal in canonical mode), the only way to detect the end of
230+ // the read/write I/O space is to continue to read/write until
231+ // EAGAIN.
232+
233+ // For stream-oriented files (e.g., pipe, FIFO, stream socket),
234+ // the condition that the read/write I/O space is exhausted can
235+ // also be detected by checking the amount of data read from /
236+ // written to the target file descriptor. For example, if you
237+ // call read(2) by asking to read a certain amount of data and
238+ // read(2) returns a lower number of bytes, you can be sure of
239+ // having exhausted the read I/O space for the file descriptor.
240+ // The same is true when writing using write(2). (Avoid this
241+ // latter technique if you cannot guarantee that the monitored
242+ // file descriptor always refers to a stream-oriented file.)
243+ if n < len (rbuf ) {
244+ break
222245 }
223246 }
224247}
0 commit comments