@@ -215,10 +215,33 @@ func (e *MultiEventLoop) doRead(c *Conn, rbuf []byte) {
215
215
handleData (c , & e .options , rbuf [:n ])
216
216
}
217
217
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
222
245
}
223
246
}
224
247
}
0 commit comments