Allenxuxu / gev

🚀Gev is a lightweight, fast non-blocking TCP network library / websocket server based on Reactor mode. Support custom protocols to quickly and easily build high-performance servers.
MIT License
1.72k stars 193 forks source link

EpollWait循环中wakeHandlerRead()是不是处理早了 #131

Closed M6ZeroG closed 1 year ago

M6ZeroG commented 1 year ago

https://github.com/Allenxuxu/gev/blob/e0a684e2ec1b6bfb3b1ab6a7b29011392795c7b5/poller/epoll.go#L158-L185

  1. 从作用上看,设置eventLoopLocal的needWake标志是为了让一次epoll循环中,Epollwait监听到来自EventFd的unix.EPOLLIN事件返回后直至dopendingFunc中取taskQueue前都不发生多余的write EventFd进而下次触发多余的唤醒。
  2. 按照epollwait + for 的模式处理事件,在Read EventFd之前多次write EventFd会被Read EventFd一次性读完,并不会引起下次多余的唤醒(EventFd在这里有点边缘触发的感觉),那么含有Read EventFd的wakeHandlerRead()只要在取taskQueue前一刻调用,实际上是具有needWake标志同样的作用。
  3. 从目前的代码观察,在处理Epollwait返回事件的for循环中,碰到EventFd就被会调用wakeHandlerRead()处理,然而从wakeHandlerRead()被调用直到dopendingFunc中取taskQueue前这个空档期只能用needWake标志来约束write EventFd不发生,那倒不如将wakeHandlerRead()推迟到取taskQueue之前,needWake标志就不需要存在了?
Allenxuxu commented 1 year ago
fd := int(events[i].Fd) 
 if fd != ep.eventFd { 

events[i] 数组里如果有多个 eventFD, 这里就可以只需回调一次。