@@ -79,9 +79,6 @@ bool EpollFdEvent::enable()
79
79
if (events_ & kExceptEvent )
80
80
++d_->except_event_num ;
81
81
82
- if (events_ & kHupEvent )
83
- ++d_->hup_event_num ;
84
-
85
82
d_->fd_events .push_back (this );
86
83
87
84
reloadEpoll ();
@@ -104,9 +101,6 @@ bool EpollFdEvent::disable()
104
101
if (events_ & kExceptEvent )
105
102
--d_->except_event_num ;
106
103
107
- if (events_ & kHupEvent )
108
- --d_->hup_event_num ;
109
-
110
104
auto iter = std::find (d_->fd_events .begin (), d_->fd_events .end (), this );
111
105
d_->fd_events .erase (iter);
112
106
@@ -136,9 +130,6 @@ void EpollFdEvent::reloadEpoll()
136
130
if (d_->except_event_num > 0 )
137
131
new_events |= EPOLLERR;
138
132
139
- if (d_->hup_event_num > 0 )
140
- new_events |= EPOLLHUP;
141
-
142
133
d_->ev .events = new_events;
143
134
144
135
if (old_events == 0 ) {
@@ -158,6 +149,7 @@ void EpollFdEvent::OnEventCallback(uint32_t events, void *obj)
158
149
EpollFdSharedData *d = static_cast <EpollFdSharedData*>(obj);
159
150
160
151
short tbox_events = 0 ;
152
+
161
153
if (events & EPOLLIN) {
162
154
events &= ~EPOLLIN;
163
155
tbox_events |= kReadEvent ;
@@ -173,29 +165,33 @@ void EpollFdEvent::OnEventCallback(uint32_t events, void *obj)
173
165
tbox_events |= kExceptEvent ;
174
166
}
175
167
168
+ bool is_got_hup = false ;
169
+
176
170
if (events & EPOLLHUP) {
177
171
events &= ~EPOLLHUP;
178
- tbox_events |= kHupEvent ;
172
+ is_got_hup = true ;
179
173
}
180
174
181
175
// ! 要先复制一份,因为在for中很可能会改动到d->fd_events,引起迭代器失效问题
182
176
auto tmp = d->fd_events ;
183
- for (auto event : tmp)
177
+ for (auto event : tmp) {
184
178
event->onEvent (tbox_events);
185
179
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
+
186
189
if (events)
187
190
LogWarn (" unhandle events:%08X, fd:%d" , events, d->fd );
188
191
}
189
192
190
193
void EpollFdEvent::onEvent (short events)
191
194
{
192
- /* *
193
- * 由于EPOLLHUP会一直触发,所以无论事件有没有监听HupEvent,只要发生了EPOLLHUB事件,
194
- * 对应fd所有的事件都要强制disable()。否则会导致Loop空跑问题。
195
- */
196
- if (events & kHupEvent )
197
- disable ();
198
-
199
195
if (events_ & events) {
200
196
if (is_stop_after_trigger_)
201
197
disable ();
0 commit comments