Don't skip events when a devpoll-like engine deletes a socket.
authorMichael Poole <mdpoole@troilus.org>
Tue, 6 Aug 2013 03:04:54 +0000 (23:04 -0400)
committerMichael Poole <mdpoole@troilus.org>
Tue, 6 Aug 2013 03:04:54 +0000 (23:04 -0400)
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.

ircd/engine_devpoll.c
ircd/engine_epoll.c
ircd/engine_kqueue.c

index e4fd20042120a216556f95cef53bb6b860170a4a..34b90330530e1e9c838c03ef8e84724246091556 100644 (file)
@@ -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];
index 080f42a9b1c4ef00bdc770e6ad0833e7934e7545..a9be73735ea97fe7b7bfdbf8a2a53fd94feaa5bf 100644 (file)
@@ -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);
index b3f535f7d8db52825068a42f959ac06d62cadd9b..a0d00dd645b5d35a49e3f350e142732f4d0cfb34 100644 (file)
@@ -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 */