INN commit: branches/2.5/innd (chan.c)

INN Commit rra at isc.org
Sat Mar 21 13:37:55 UTC 2015


    Date: Saturday, March 21, 2015 @ 06:37:54
  Author: iulius
Revision: 9801

Improve the count of sleeping channels

The highest file descriptor of sleeping channels was not always properly
updated.  A new CHANresetlastsleeping() function now does the job 
when called.

Also prevent innd from crashing if a channel is supposed to sleep but
does not have a Waker set.

Thanks to Petr Novopashenniy for the bug report.

Modified:
  branches/2.5/innd/chan.c

--------+
 chan.c |   35 ++++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

Modified: chan.c
===================================================================
--- chan.c	2015-03-21 13:37:12 UTC (rev 9800)
+++ chan.c	2015-03-21 13:37:54 UTC (rev 9801)
@@ -571,6 +571,21 @@
 
 
 /*
+**  When removing a channel from the sleep mask, we want to lower the last
+**  file descriptor if we removed the highest one.  Called from SCHANremove.
+*/
+static void
+CHANresetlastsleeping(int fd)
+{
+    if (fd == channels.max_sleep_fd) {
+        while (   !FD_ISSET(channels.max_sleep_fd, &channels.sleep_set)
+               && channels.max_sleep_fd > 1)
+            channels.max_sleep_fd--;
+    }
+}
+
+
+/*
 **  Mark a channel as an active reader.
 */
 void
@@ -629,8 +644,6 @@
 void
 SCHANremove(CHANNEL *cp)
 {
-    int fd;
-
     if (!CHANsleeping(cp))
         return;
     FD_CLR(cp->fd, &channels.sleep_set);
@@ -638,12 +651,7 @@
     cp->Waketime = 0;
 
     /* If this was the highest descriptor, get a new highest. */
-    if (cp->fd == channels.max_sleep_fd) {
-        fd = channels.max_sleep_fd;
-        while (!FD_ISSET(fd, &channels.sleep_set) && fd > 1)
-            fd--;
-        channels.max_sleep_fd = fd;
-    }
+    CHANresetlastsleeping(cp->fd);
 }
 
 
@@ -1276,12 +1284,21 @@
                 if (cp->Type == CTfree) {
                     warn("%s %d free but was in SMASK", CHANname(cp), fd);
                     FD_CLR(fd, &channels.sleep_set);
+                    channels.sleep_count--;
+                    CHANresetlastsleeping(fd);
                     close(fd);
                     cp->fd = -1;
                 } else {
                     cp->LastActive = Now.tv_sec;
                     SCHANremove(cp);
-                    (*cp->Waker)(cp);
+                    if (cp->Waker != NULL) {
+                        (*cp->Waker)(cp);
+                    } else {
+                        name = CHANname(cp);
+                        warn("%s %d sleeping without Waker", name, fd);
+                        SITEchanclose(cp);
+                        CHANclose(cp, name);
+                    }
                 }
             }
 



More information about the inn-committers mailing list