From: Michael Poole Date: Tue, 6 Aug 2013 03:04:54 +0000 (-0400) Subject: Don't skip events when a devpoll-like engine deletes a socket. X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=commitdiff_plain;h=41c732d83f3097645dc43ece14f38547045d1d0d Don't skip events when a devpoll-like engine deletes a socket. engine_delete() might replace polls[polls_i] with polls[--polls_used], but neither it nor engine_loop() decremented polls_i so that the moved event would be processed. We can eliminate polls_i while fixing it. --- diff --git a/ircd/engine_devpoll.c b/ircd/engine_devpoll.c index e4fd200..34b9033 100644 --- a/ircd/engine_devpoll.c +++ b/ircd/engine_devpoll.c @@ -78,8 +78,6 @@ static struct Timer clear_error; static struct pollfd *polls; /** Number of ::polls elements that have been populated. */ static int polls_used; -/** Current processing position in ::polls. */ -static int polls_i; /** Decrement the error count (once per hour). * @param[in] ev Expired timer event (ignored). @@ -273,7 +271,7 @@ engine_delete(struct Socket* sock) sockList[s_fd(sock)] = 0; /* zero the socket list entry */ /* Drop any unprocessed events citing this socket. */ - for (ii = polls_i; ii < polls_used; ii++) { + for (ii = 0; ii < polls_used; ii++) { if (polls[ii].fd == s_fd(sock)) { polls[ii] = polls[--polls_used]; } @@ -336,8 +334,8 @@ engine_loop(struct Generators* gen) continue; } - for (polls_i = 0; polls_i < polls_used; polls_i++) { - pfd = &polls[polls_i]; + while (polls_used > 0) { + pfd = &polls[--polls_used]; assert(-1 < pfd->fd); sock = sockList[pfd->fd]; diff --git a/ircd/engine_epoll.c b/ircd/engine_epoll.c index 080f42a..a9be737 100644 --- a/ircd/engine_epoll.c +++ b/ircd/engine_epoll.c @@ -108,8 +108,6 @@ static struct Timer clear_error; static struct epoll_event *events; /** Number of ::events elements that have been populated. */ static int events_used; -/** Current processing position in ::events. */ -static int events_i; /** Decrement the error count (once per hour). * @param[in] ev Expired timer event (ignored). @@ -248,7 +246,7 @@ engine_delete(struct Socket *sock) Debug((DEBUG_ENGINE, "epoll: Deleting socket %d [%p], state %s", s_fd(sock), sock, state_to_name(s_state(sock)))); /* Drop any unprocessed events citing this socket. */ - for (ii = events_i; ii < events_used; ii++) { + for (ii = 0; ii < events_used; ii++) { if (events[ii].data.ptr == sock) { events[ii] = events[--events_used]; } @@ -293,8 +291,8 @@ engine_loop(struct Generators *gen) continue; } - for (events_i = 0; events_i < events_used; ) { - evt = &events[events_i++]; + while (events_used > 0) { + evt = &events[--events_used]; if (!(sock = evt->data.ptr)) continue; gen_ref_inc(sock); diff --git a/ircd/engine_kqueue.c b/ircd/engine_kqueue.c index b3f535f..a0d00dd 100644 --- a/ircd/engine_kqueue.c +++ b/ircd/engine_kqueue.c @@ -53,8 +53,6 @@ static int kqueue_id; static struct kevent *events; /** Number of ::events elements that have been populated. */ static int events_used; -/** Current processing position in ::events. */ -static int events_i; /** Number of recent errors from kqueue. */ static int errors = 0; @@ -293,7 +291,7 @@ engine_delete(struct Socket* sock) sockList[s_fd(sock)] = 0; /* Drop any unprocessed events citing this socket. */ - for (ii = events_i; ii < events_used; ii++) { + for (ii = 0; ii < events_used; ii++) { if (events[ii].ident == s_fd(sock)) { events[ii] = events[--events_used]; } @@ -353,8 +351,8 @@ engine_loop(struct Generators* gen) continue; } - for (events_i = 0; events_i < events_used; events_i++) { - evt = &events[events_i]; + while (events_used > 0) { + evt = &events[--events_used]; if (evt->filter == EVFILT_SIGNAL) { /* it's a signal; deal appropriately */