* WebCit thread pool is no longer tied to the number of server sessions. MIN_WORKER_...
authorArt Cancro <ajc@citadel.org>
Mon, 24 May 2010 17:31:47 +0000 (17:31 +0000)
committerArt Cancro <ajc@citadel.org>
Mon, 24 May 2010 17:31:47 +0000 (17:31 +0000)
webcit/context_loop.c
webcit/sysdep.c
webcit/webcit.h
webcit/webserver.c

index 1525e91a574d1476e45661e53c09c99a540ffc52..efa864f008595ec7b03d32856050e11006e47d98 100644 (file)
@@ -21,7 +21,10 @@ pthread_key_t MyConKey;         /* TSD key for MySession() */
 HashList *HttpReqTypes = NULL;
 HashList *HttpHeaderHandler = NULL;
 extern HashList *HandlerHash;
-int num_threads = 1;           /* Number of worker threads.  Start at 1 because the parent counts. */
+
+/* the following two values start at 1 because the initial parent thread counts as one. */
+int num_threads_existing = 1;          /* Number of worker threads which exist. */
+int num_threads_executing = 1;         /* Number of worker threads currently executing. */
 
 void DestroyHttpHeaderHandler(void *V)
 {
@@ -44,16 +47,13 @@ void do_housekeeping(void)
 {
        wcsession *sptr, *ss;
        wcsession *sessions_to_kill = NULL;
-       int num_sessions = 0;
 
        /*
         * Lock the session list, moving any candidates for euthanasia into
         * a separate list.
         */
        pthread_mutex_lock(&SessionListMutex);
-       num_sessions = 0;
        for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
-               ++num_sessions;
 
                /* Kill idle sessions */
                if ((time(NULL) - (sptr->lastreq)) > (time_t) WEBCIT_TIMEOUT) {
@@ -90,18 +90,19 @@ void do_housekeeping(void)
 
                session_destroy_modules(&sessions_to_kill);
                sessions_to_kill = sptr;
-               --num_sessions;
        }
 
        /*
-        * If there are more sessions than threads, then we should spawn
-        * more threads ... up to a predefined maximum.
+        * Check the size of our thread pool.  If all threads are executing, spawn another.
         */
-       while ( (num_sessions > num_threads) && (num_threads <= MAX_WORKER_THREADS) ) {
+       begin_critical_section(S_SPAWNER);
+       while (
+               (num_threads_executing >= num_threads_existing)
+               && (num_threads_existing <= MAX_WORKER_THREADS)
+       ) {
                spawn_another_worker_thread();
-               lprintf(3, "There are %d sessions and %d threads active.\n",
-                       num_sessions, num_threads);
        }
+       end_critical_section(S_SPAWNER);
 }
 
 
index e2155814fa9f78884418c0d853053f7d56001b20..432966687a7b646fc3e8f5dbcd64dbfbb91b2c0b 100644 (file)
@@ -155,9 +155,10 @@ void worker_entry(void)
                ssock = -1; 
                errno = EAGAIN;
                do {
+                       --num_threads_executing;
                        ssock = accept(msock, NULL, 0);
+                       ++num_threads_executing;
                        lprintf(9, "Thread %u woke up, accept() returned %d %s\n",
-                               ((pthread_self() % 6) + 1),
                                pthread_self(),
                                ssock,
                                ((ssock >= 0) ? "" : strerror(errno))
@@ -168,8 +169,8 @@ void worker_entry(void)
                {/* ok, we're going down. */
                        int shutdown = 0;
 
-                       /* the first to come here will have to do the cleanup.
-                        * make shure its realy just one.
+                       /* The first thread to get here will have to do the cleanup.
+                        * Make sure it's really just one.
                         */
                        begin_critical_section(S_SHUTDOWN);
                        if (msock == -1)
@@ -198,15 +199,16 @@ void worker_entry(void)
                }
                if (ssock < 0 ) continue;
 
+               /* Now do something. */
                if (msock < 0) {
                        if (ssock > 0) close (ssock);
-                       lprintf(2, "inbetween.");
+                       lprintf(2, "in between.");
                        pthread_exit(NULL);
-               } else { /* Got it? do some real work! */
+               } else {
+                       /* Got it? do some real work! */
                        /* Set the SO_REUSEADDR socket option */
                        i = 1;
-                       setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR,
-                                  &i, sizeof(i));
+                       setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
 
                        /* If we are an HTTPS server, go crypto now. */
 #ifdef HAVE_OPENSSL
@@ -244,8 +246,9 @@ void worker_entry(void)
 #endif
 
                                /* ...and close the socket. */
-                               if (Hdr.http_sock > 0)
+                               if (Hdr.http_sock > 0) {
                                        lingering_close(ssock);
+                               }
                                http_detach_modules(&Hdr);
 
                        }
@@ -422,7 +425,10 @@ void spawn_another_worker_thread()
        pthread_attr_t attr;    /* Thread attributes */
        int ret;
 
-       lprintf(3, "Creating a new thread.  Pool size is now %d\n", ++num_threads);
+       lprintf(3, "Creating a new thread.\n");
+
+       ++num_threads_existing;
+       ++num_threads_executing;
 
        /* set attributes for the new thread */
        pthread_attr_init(&attr);
index b8f0d4e1238ee256bbad3c8bbd350bff1bff3761..4e9442f44cd380c0d9ecc2bcd941da6edff160b7 100644 (file)
@@ -134,7 +134,6 @@ extern char *ssl_cipher_list;
 #define DEFAULT_PORT           "504"
 #define TARGET                 "webcit01"      /* Target for inline URL's */
 #define HOUSEKEEPING           15              /* Housekeeping frequency */
-#define MIN_WORKER_THREADS     5
 #define MAX_WORKER_THREADS     250
 #define LISTEN_QUEUE_LENGTH    100             /* listen() backlog queue */
 
@@ -588,6 +587,7 @@ void RegisterHeaderHandler(const char *Name, long Len, Header_Evaluator F);
 
 enum {
        S_SHUTDOWN,
+       S_SPAWNER,
        MAX_SEMAPHORES
 };
 
@@ -619,7 +619,8 @@ extern int is_https;
 extern int setup_wizard;
 extern char wizard_filename[];
 extern int follow_xff;
-extern int num_threads;
+extern int num_threads_existing;
+extern int num_threads_executing;
 
 void InitialiseSemaphores(void);
 void begin_critical_section(int which_one);
index 97c1bfb12308e9e1f0372b89df3710af36deb35e..243a291329c17b73ca433432f1c24803ba423f66 100644 (file)
@@ -77,7 +77,7 @@ int main(int argc, char **argv)
        size_t basesize = 2;            /* how big should strbufs be on creation? */
        pthread_t SessThread;           /* Thread descriptor */
        pthread_attr_t attr;            /* Thread attributes */
-       int a, i;                       /* General-purpose variables */
+       int a;                          /* General-purpose variable */
        char tracefile[PATH_MAX];
        char ip_addr[256]="0.0.0.0";
        int relh=0;
@@ -348,12 +348,7 @@ int main(int argc, char **argv)
 #endif
        drop_root(UID);
 
-       /* Start a few initial worker threads */
-       for (i = 0; i < (MIN_WORKER_THREADS); ++i) {
-               spawn_another_worker_thread();
-       }
-
-       /* now the original thread becomes another worker */
+       /* Become a worker thread.  More worker threads will be spawned as they are needed. */
        worker_entry();
        ShutDownLibCitadel ();
        return 0;