]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Make max_requests_per_server work
authorAlan T. DeKok <aland@freeradius.org>
Fri, 13 Sep 2013 12:44:37 +0000 (08:44 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 13 Sep 2013 12:45:08 +0000 (08:45 -0400)
src/main/threads.c

index 2cf760165e7c0a3f3448fda5ae01860660df21cb..3910904a0d17c11a6fdc54b3f4146538e4982b99 100644 (file)
@@ -131,6 +131,7 @@ typedef struct THREAD_POOL {
        THREAD_HANDLE *tail;
 
        int active_threads;     /* protected by queue_mutex */
+       int exited_threads;
        int total_threads;
        int max_thread_num;
        int start_threads;
@@ -326,7 +327,8 @@ int request_enqueue(REQUEST *request)
         *      go manage it.
         */
        if ((last_cleaned < request->timestamp) ||
-           (thread_pool.active_threads == thread_pool.total_threads)) {
+           (thread_pool.active_threads == thread_pool.total_threads) ||
+           (thread_pool.exited_threads > 0)) {
                thread_pool_manage(request->timestamp);
        }
 
@@ -595,6 +597,9 @@ static int request_dequeue(REQUEST **prequest)
        return 1;
 }
 
+#undef DEBUG2
+#define DEBUG2(fmt, ...)       radlog(L_INFO, fmt, ## __VA_ARGS__)
+
 
 /*
  *     The main thread handler for requests.
@@ -692,6 +697,17 @@ static void *request_handler_thread(void *arg)
                rad_assert(thread_pool.active_threads > 0);
                thread_pool.active_threads--;
                pthread_mutex_unlock(&thread_pool.queue_mutex);
+
+               /*
+                *      If the thread has handled too many requests, then make it
+                *      exit.
+                */
+               if ((thread_pool.max_requests_per_thread > 0) &&
+                   (self->request_count >= thread_pool.max_requests_per_thread)) {
+                       DEBUG2("Thread %d handled too many requests",
+                              self->thread_num);
+                       break;
+               }
        } while (self->status != THREAD_CANCELLED);
 
        DEBUG2("Thread %d exiting...", self->thread_num);
@@ -705,6 +721,10 @@ static void *request_handler_thread(void *arg)
        ERR_remove_state(0);
 #endif
 
+       pthread_mutex_lock(&thread_pool.queue_mutex);
+       thread_pool.exited_threads++;
+       pthread_mutex_unlock(&thread_pool.queue_mutex);
+
        /*
         *  Do this as the LAST thing before exiting.
         */
@@ -1085,6 +1105,25 @@ static void thread_pool_manage(time_t now)
        THREAD_HANDLE *handle, *next;
        int active_threads;
 
+       /*
+        *      Loop over the thread pool, deleting exited threads.
+        */
+       for (handle = thread_pool.head; handle; handle = next) {
+               next = handle->next;
+
+               /*
+                *      Maybe we've asked the thread to exit, and it
+                *      has agreed.
+                */
+               if (handle->status == THREAD_EXITED) {
+                       pthread_join(handle->pthread_id, NULL);
+                       delete_thread(handle);
+                       pthread_mutex_lock(&thread_pool.queue_mutex);
+                       thread_pool.exited_threads--;
+                       pthread_mutex_unlock(&thread_pool.queue_mutex);
+               }
+       }
+
        /*
         *      We don't need a mutex lock here, as we're reading
         *      active_threads, and not modifying it.  We want a close
@@ -1141,22 +1180,6 @@ static void thread_pool_manage(time_t now)
        }
        last_cleaned = now;
 
-       /*
-        *      Loop over the thread pool, deleting exited threads.
-        */
-       for (handle = thread_pool.head; handle; handle = next) {
-               next = handle->next;
-
-               /*
-                *      Maybe we've asked the thread to exit, and it
-                *      has agreed.
-                */
-               if (handle->status == THREAD_EXITED) {
-                       pthread_join(handle->pthread_id, NULL);
-                       delete_thread(handle);
-               }
-       }
-
        /*
         *      Only delete the spare threads if sufficient time has
         *      passed since we last created one.  This helps to minimize
@@ -1208,27 +1231,6 @@ static void thread_pool_manage(time_t now)
                }
        }
 
-       /*
-        *      If the thread has handled too many requests, then make it
-        *      exit.
-        */
-       if (thread_pool.max_requests_per_thread > 0) {
-               for (handle = thread_pool.head; handle; handle = next) {
-                       next = handle->next;
-
-                       /*
-                        *      Not handling a request, but otherwise
-                        *      live, we can kill it.
-                        */
-                       if ((handle->request == NULL) &&
-                           (handle->status == THREAD_RUNNING) &&
-                           (handle->request_count > thread_pool.max_requests_per_thread)) {
-                               handle->status = THREAD_CANCELLED;
-                               sem_post(&thread_pool.semaphore);
-                       }
-               }
-       }
-
        /*
         *      Otherwise everything's kosher.  There are not too few,
         *      or too many spare threads.  Exit happily.