@@ -79,9 +79,6 @@ bool EpollFdEvent::enable()
7979 if (events_ & kExceptEvent )
8080 ++d_->except_event_num ;
8181
82- if (events_ & kHupEvent )
83- ++d_->hup_event_num ;
84-
8582 d_->fd_events .push_back (this );
8683
8784 reloadEpoll ();
@@ -104,9 +101,6 @@ bool EpollFdEvent::disable()
104101 if (events_ & kExceptEvent )
105102 --d_->except_event_num ;
106103
107- if (events_ & kHupEvent )
108- --d_->hup_event_num ;
109-
110104 auto iter = std::find (d_->fd_events .begin (), d_->fd_events .end (), this );
111105 d_->fd_events .erase (iter);
112106
@@ -136,9 +130,6 @@ void EpollFdEvent::reloadEpoll()
136130 if (d_->except_event_num > 0 )
137131 new_events |= EPOLLERR;
138132
139- if (d_->hup_event_num > 0 )
140- new_events |= EPOLLHUP;
141-
142133 d_->ev .events = new_events;
143134
144135 if (old_events == 0 ) {
@@ -158,6 +149,7 @@ void EpollFdEvent::OnEventCallback(uint32_t events, void *obj)
158149 EpollFdSharedData *d = static_cast <EpollFdSharedData*>(obj);
159150
160151 short tbox_events = 0 ;
152+
161153 if (events & EPOLLIN) {
162154 events &= ~EPOLLIN;
163155 tbox_events |= kReadEvent ;
@@ -173,29 +165,33 @@ void EpollFdEvent::OnEventCallback(uint32_t events, void *obj)
173165 tbox_events |= kExceptEvent ;
174166 }
175167
168+ bool is_got_hup = false ;
169+
176170 if (events & EPOLLHUP) {
177171 events &= ~EPOLLHUP;
178- tbox_events |= kHupEvent ;
172+ is_got_hup = true ;
179173 }
180174
181175 // ! 要先复制一份,因为在for中很可能会改动到d->fd_events,引起迭代器失效问题
182176 auto tmp = d->fd_events ;
183- for (auto event : tmp)
177+ for (auto event : tmp) {
184178 event->onEvent (tbox_events);
185179
180+ // ! 在epoll中,无论有没有监听EPOLLHUP,在对端close了fd时都会触发本端EPOLLHUP事件
181+ // ! 只要发生了EPOLLHUB事件,只有让上层关闭该事件所有的事件才能停止EPOLLHUP的触发
182+ // ! 否则它会一直触发事件,导致Loop空跑,CPU占满问题
183+ if (is_got_hup) {
184+ // ! 将HUP事件当成可读事件,上层读到0字节则表示对端已关闭
185+ event->onEvent (kReadEvent );
186+ }
187+ }
188+
186189 if (events)
187190 LogWarn (" unhandle events:%08X, fd:%d" , events, d->fd );
188191}
189192
190193void EpollFdEvent::onEvent (short events)
191194{
192- /* *
193- * 由于EPOLLHUP会一直触发,所以无论事件有没有监听HupEvent,只要发生了EPOLLHUB事件,
194- * 对应fd所有的事件都要强制disable()。否则会导致Loop空跑问题。
195- */
196- if (events & kHupEvent )
197- disable ();
198-
199195 if (events_ & events) {
200196 if (is_stop_after_trigger_)
201197 disable ();
0 commit comments