Fix race condition that caused segfaults in imap and xmpp as seen on
authorDave West <davew@uncensored.citadel.org>
Sun, 10 Jan 2010 12:41:01 +0000 (12:41 +0000)
committerDave West <davew@uncensored.citadel.org>
Sun, 10 Jan 2010 12:41:01 +0000 (12:41 +0000)
uncensored.
The race was that a new connection could begin doing its greeting
function and another thread could begin the connections command loop
function before the greeting had completed setting up the connection
environment.

citadel/context.h
citadel/sysdep.c

index 24cfc6861a586b4a5eb7226062e88fba57277d48..b8e48c42ab90c58a141f79dae37d59b454af6463 100644 (file)
@@ -126,7 +126,8 @@ typedef struct CitContext CitContext;
  */
 enum {
        CON_IDLE,               /* This context is doing nothing */
-       CON_STARTING,           /* This context needs the greeting outputting */
+       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 */
 };
index dfe3278f1089fff814f5262885354318747499dd..3d2db7da8d565170816a83fdd35054d4ce094d09 100644 (file)
@@ -935,8 +935,9 @@ do_select:  force_purge = 0;
                                ptr->state = CON_EXECUTING;
                                break;
                        }
-                       if ((bind_me == NULL) && (ptr->state == CON_STARTING)) {
+                       if ((bind_me == NULL) && (ptr->state == CON_GREETING)) {
                                bind_me = ptr;
+                               ptr->state = CON_STARTING;
                                break;
                        }
                }
@@ -1153,7 +1154,7 @@ void *select_on_master (void *arg)
                                                SO_REUSEADDR,
                                                &i, sizeof(i));
 
-                                       con->state = CON_STARTING;
+                                       con->state = CON_GREETING;
 
                                        retval--;
                                        if (retval == 0)