THREAD_HANDLE *tail;
int active_threads; /* protected by queue_mutex */
+ int exited_threads;
int total_threads;
int max_thread_num;
int start_threads;
* 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);
}
return 1;
}
+#undef DEBUG2
+#define DEBUG2(fmt, ...) radlog(L_INFO, fmt, ## __VA_ARGS__)
+
/*
* The main thread handler for requests.
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);
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.
*/
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
}
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
}
}
- /*
- * 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.