make shure invalid session fd's don't get set into the central select.
authorWilfried Goesgens <dothebart@citadel.org>
Sat, 9 Jul 2011 20:50:48 +0000 (20:50 +0000)
committerWilfried Goesgens <dothebart@citadel.org>
Sat, 9 Jul 2011 20:50:48 +0000 (20:50 +0000)
citadel/context.c
citadel/context.h
citadel/sysdep.c

index 382acb47f3d0ea8721fab322c217b936dbf40b7d..8e433c7a3b8dd198240eacf7c8fb50ee3cdcb403 100644 (file)
@@ -460,7 +460,7 @@ CitContext *CloneContext(CitContext *CloneMe) {
 
        me->MigrateBuf = NewStrBuf();
        me->RecvBuf.Buf = NewStrBuf();
-
+       
        begin_critical_section(S_SESSION_TABLE);
        {
                me->cs_pid = ++next_pid;
@@ -523,6 +523,7 @@ void CtdlFillSystemContext(CitContext *context, char *name)
        len = cutuserkey(sysname);
        memcpy(context->curr_user, sysname, len + 1);
        context->client_socket = (-1);
+       context->state = CON_SYS;
 
        /* internal_create_user has the side effect of loading the user regardless of wether they
         * already existed or needed to be created
index eb9b01d2c0ade55df38828fe2d5d3213f494a3b2..cb7d92f0293f3b451ad85b0930429a6b1dbf92de 100644 (file)
@@ -9,6 +9,26 @@
 #include "threads.h"
 
 
+/*
+ * Values for CitContext.state
+ * 
+ * A session that is doing nothing is in CON_IDLE state.  When activity
+ * is detected on the socket, it goes to CON_READY, indicating that it
+ * needs to have a worker thread bound to it.  When a thread binds to
+ * the session, it goes to CON_EXECUTING and does its thing.  When the
+ * transaction is finished, the thread sets it back to CON_IDLE and lets
+ * it go.
+ */
+typedef enum __CCState {
+       CON_IDLE,               /* This context is doing nothing */
+       CON_GREETING,           /* This context needs to output its greeting */
+       CON_STARTING,           /* This context is outputting its greeting */
+       CON_READY,              /* This context needs attention */
+       CON_EXECUTING,          /* This context is bound to a thread */
+       CON_SYS                 /* This is a system context and mustn't be purged */
+} CCState;
+
+
 /*
  * Here's the big one... the Citadel context structure.
  *
@@ -24,7 +44,7 @@ struct CitContext {
        int dont_term;          /* for special activities like artv so we don't get killed */
        time_t lastcmd;         /* time of last command executed */
        time_t lastidle;        /* For computing idle time */
-       int state;              /* thread state (see CON_ values below) */
+       CCState state;          /* thread state (see CON_ values below) */
        int kill_me;            /* Set to nonzero to flag for termination */
 
        IOBuffer SendBuf, /* Our write Buffer */
@@ -123,23 +143,6 @@ struct CitContext {
 
 typedef struct CitContext CitContext;
 
-/*
- * Values for CitContext.state
- * 
- * A session that is doing nothing is in CON_IDLE state.  When activity
- * is detected on the socket, it goes to CON_READY, indicating that it
- * needs to have a worker thread bound to it.  When a thread binds to
- * the session, it goes to CON_EXECUTING and does its thing.  When the
- * transaction is finished, the thread sets it back to CON_IDLE and lets
- * it go.
- */
-enum {
-       CON_IDLE,               /* This context is doing nothing */
-       CON_GREETING,           /* This context needs to output its greeting */
-       CON_STARTING,           /* This context is outputting its greeting */
-       CON_READY,              /* This context needs attention */
-       CON_EXECUTING           /* This context is bound to a thread */
-};
 
 #define CC MyContext()
 
index 74330fe12f914b75e91510437565c63d9d473f30..1c7df5e9c4857333406d8e68a7aa3a96cf57bc4c 100644 (file)
@@ -1266,11 +1266,13 @@ do_select:      force_purge = 0;
                begin_critical_section(S_SESSION_TABLE);
                for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
                        int client_socket;
+                       if ((ptr->state == CON_SYS) && (ptr->client_socket == 0))
+                           continue;
                        client_socket = ptr->client_socket;
                        /* Dont select on dead sessions only truly idle ones */
                        if ((ptr->state == CON_IDLE) && 
                            (CC->kill_me == 0) &&
-                           (client_socket != -1))
+                           (client_socket > 0))
                        {
                                FD_SET(client_socket, &readfds);
                                if (client_socket > highest)