Fix a subtle race condition between prepare_csp_for_next_request() and sweep()
authorFabian Keil <fk@fabiankeil.de>
Sun, 6 Nov 2011 11:58:51 +0000 (11:58 +0000)
committerFabian Keil <fk@fabiankeil.de>
Sun, 6 Nov 2011 11:58:51 +0000 (11:58 +0000)
A thread preparing itself for the next client request
could briefly appear to be inactive.

If all other threads were already using more recent files,
the thread could get its files swept away under its feet,
later on causing an 'invalid read of size 1' when the file
name was logged in any_loaded_file_changed().

I've only seen it while stress testing in valgrind while
touching action files in a loop. It's unlikely to have
caused any actual problems in the real world.

jcc.c

diff --git a/jcc.c b/jcc.c
index 946acb0..49f78d6 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.372 2011/10/30 16:20:12 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.373 2011/11/06 11:48:23 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -2444,6 +2444,8 @@ static void chat(struct client_state *csp)
  *********************************************************************/
 static void prepare_csp_for_next_request(struct client_state *csp)
 {
+   unsigned int toggled_on_flag_set = (0 != (csp->flags & CSP_FLAG_TOGGLED_ON));
+
    csp->content_type = 0;
    csp->content_length = 0;
    csp->expected_content_length = 0;
@@ -2462,9 +2464,11 @@ static void prepare_csp_for_next_request(struct client_state *csp)
       csp->fwd = NULL;
    }
    /* XXX: Store per-connection flags someplace else. */
-   csp->flags &= CSP_FLAG_TOGGLED_ON;
-   csp->flags |= CSP_FLAG_ACTIVE;
-   csp->flags |= CSP_FLAG_REUSED_CLIENT_CONNECTION;
+   csp->flags = (CSP_FLAG_ACTIVE | CSP_FLAG_REUSED_CLIENT_CONNECTION);
+   if (toggled_on_flag_set)
+   {
+      csp->flags |= CSP_FLAG_TOGGLED_ON;
+   }
 }
 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */