Skip to content

Commit

Permalink
lib: Correctly handle ppoll pfds.events == 0
Browse files Browse the repository at this point in the history
The frrevent system is spitting out this message in bgpd:
20:40:15 mem1-roc-f2-b1-r5-t2-d4 bgpd[13166]: [XETTR-D5MR0][EC 100663316] Attempting to process an I/O event but for fd: 214(8) no thread to handle this!

This is because as each io event is processed, it is possible that a
.events is set to 0.  This can leave a situation where we ask
ppoll to handle anything that happens on a fd with a .events of 0,
in this situation ppoll can return POLLERR, which indicates that
something bad has happened on the fd.

Let's set the ppoll fds.fd value to -1 when there are no more
events to be processed.  ppoll specifically calls out that
it will just skip this particular one.

Signed-off-by: Donald Sharp <[email protected]>
  • Loading branch information
donaldsharp committed Oct 17, 2024
1 parent 466efab commit d11ad98
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion lib/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ void _event_add_read_write(const struct xref_eventsched *xref,
* if we already have a pollfd for our file descriptor, find and
* use it
*/
for (nfds_t i = 0; i < m->handler.pfdcount; i++)
for (nfds_t i = 0; i < m->handler.pfdcount; i++) {
if (m->handler.pfds[i].fd == fd) {
queuepos = i;

Expand All @@ -993,6 +993,15 @@ void _event_add_read_write(const struct xref_eventsched *xref,
#endif
break;
}
/*
* We are setting the fd = -1 for the
* case when a read/write event is going
* away. if we find a -1 we can stuff it
* into that spot, so note it
*/
if (m->handler.pfds[i].fd == -1 && queuepos == m->handler.pfdcount)
queuepos = i;
}

/* make sure we have room for this fd + pipe poker fd */
assert(queuepos + 1 < m->handler.pfdsize);
Expand Down Expand Up @@ -1269,6 +1278,14 @@ static void cancel_arg_helper(struct event_loop *master,
for (i = 0; i < master->handler.pfdcount;) {
pfd = master->handler.pfds + i;

/*
* Skip this spot, nothing here to see
*/
if (pfd->fd == -1) {
i++;
continue;
}

if (pfd->events & POLLIN)
t = master->read[pfd->fd];
else
Expand Down Expand Up @@ -1590,6 +1607,12 @@ static int thread_process_io_helper(struct event_loop *m, struct event *thread,
* we should.
*/
m->handler.pfds[pos].events &= ~(state);
/*
* ppoll man page says that a fd of -1 causes the particular
* array item to be skipped. So let's skip it
*/
if (m->handler.pfds[pos].events == 0)
m->handler.pfds[pos].fd = -1;

if (!thread) {
if ((actual_state & (POLLHUP|POLLIN)) != POLLHUP)
Expand Down

0 comments on commit d11ad98

Please sign in to comment.