Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/event/event_epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,20 @@ _dispatch_get_buffer_size(dispatch_muxnote_t dmn, bool writer)
return (uintptr_t)n;
}

static void
_dispatch_event_merge_hangup(dispatch_unote_t du)
{
// consumed by dux_merge_evt()
_dispatch_retain_unote_owner(du);
dispatch_unote_state_t du_state = _dispatch_unote_state(du);
du_state |= DU_STATE_NEEDS_DELETE;
du_state &= ~DU_STATE_ARMED;
_dispatch_unote_state_set(du, du_state);
uintptr_t data = 0; // EOF
os_atomic_store2o(du._dr, ds_pending_data, ~data, relaxed);
dux_merge_evt(du._du, EV_DELETE|EV_DISPATCH, data, 0);
}

static void
_dispatch_event_merge_fd(dispatch_muxnote_t dmn, uint32_t events)
{
Expand Down Expand Up @@ -583,6 +597,20 @@ _dispatch_event_merge_fd(dispatch_muxnote_t dmn, uint32_t events)
}
}

// SR-9033: EPOLLHUP is an unmaskable event which we must respond to
if (events & EPOLLHUP) {
LIST_FOREACH_SAFE(dul, &dmn->dmn_readers_head, du_link, dul_next) {
dispatch_unote_t du = _dispatch_unote_linkage_get_unote(dul);
_dispatch_event_merge_hangup(du);
}
LIST_FOREACH_SAFE(dul, &dmn->dmn_writers_head, du_link, dul_next) {
dispatch_unote_t du = _dispatch_unote_linkage_get_unote(dul);
_dispatch_event_merge_hangup(du);
}
epoll_ctl(_dispatch_epfd, EPOLL_CTL_DEL, dmn->dmn_fd, NULL);
return;
}

events = _dispatch_muxnote_armed_events(dmn);
if (events) _dispatch_epoll_update(dmn, events, EPOLL_CTL_MOD);
}
Expand Down