Terminate unused resolver threads after a timeout
authorTobias Brunner <tobias@strongswan.org>
Thu, 18 Oct 2012 06:46:24 +0000 (08:46 +0200)
committerTobias Brunner <tobias@strongswan.org>
Thu, 18 Oct 2012 10:26:00 +0000 (12:26 +0200)
man/strongswan.conf.5.in
src/libstrongswan/host_resolver.c
src/libstrongswan/host_resolver.h
src/libstrongswan/library.c

index f7233c9..c4bd6a8 100644 (file)
@@ -696,6 +696,12 @@ strength
 .BR libstrongswan.ecp_x_coordinate_only " [yes]"
 Compliance with the errata for RFC 4753
 .TP
+.BR libstrongswan.host_resolver.max_threads " [3]"
+Maximum number of concurrent resolver threads (they are terminated if unused)
+.TP
+.BR libstrongswan.host_resolver.min_threads " [0]"
+Minimum number of resolver threads to keep around
+.TP
 .BR libstrongswan.integrity_test " [no]"
 Check daemon, libstrongswan and plugin integrity at startup
 .TP
index b7e990b..5a109f0 100644 (file)
 #include <utils/hashtable.h>
 #include <utils/linked_list.h>
 
+/**
+ * Default minimum and maximum number of threads
+ */
+#define MIN_THREADS_DEFAULT 0
+#define MAX_THREADS_DEFAULT 3
+
+/**
+ * Timeout in seconds to wait for new queries until a thread may be stopped
+ */
+#define NEW_QUERY_WAIT_TIMEOUT 30
+
 typedef struct private_host_resolver_t private_host_resolver_t;
 
 /**
@@ -60,6 +71,11 @@ struct private_host_resolver_t {
        condvar_t *new_query;
 
        /**
+        * Minimum number of resolver threads
+        */
+       u_int min_threads;
+
+       /**
         * Maximum number of resolver threads
         */
        u_int max_threads;
@@ -142,15 +158,22 @@ static job_requeue_t resolve_hosts(private_host_resolver_t *this)
        struct addrinfo hints, *result;
        query_t *query;
        int error;
-       bool old;
+       bool old, timed_out;
 
        this->mutex->lock(this->mutex);
        while (this->queue->remove_first(this->queue, (void**)&query) != SUCCESS)
        {
                thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
                old = thread_cancelability(TRUE);
-               this->new_query->wait(this->new_query, this->mutex);
+               timed_out = this->new_query->timed_wait(this->new_query, this->mutex,
+                                                                                               NEW_QUERY_WAIT_TIMEOUT * 1000);
                thread_cancelability(old);
+               if (timed_out && (this->threads > this->min_threads))
+               {
+                       this->threads--;
+                       thread_cleanup_pop(TRUE);
+                       return JOB_REQUEUE_NONE;
+               }
                thread_cleanup_pop(FALSE);
        }
        this->busy_threads++;
@@ -275,7 +298,7 @@ METHOD(host_resolver_t, destroy, void,
 /*
  * Described in header
  */
-host_resolver_t *host_resolver_create(u_int max_threads)
+host_resolver_t *host_resolver_create()
 {
        private_host_resolver_t *this;
 
@@ -290,8 +313,14 @@ host_resolver_t *host_resolver_create(u_int max_threads)
                .queue = linked_list_create(),
                .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
                .new_query = condvar_create(CONDVAR_TYPE_DEFAULT),
-               .max_threads = max_threads,
        );
 
+       this->min_threads = max(0, lib->settings->get_int(lib->settings,
+                                                                       "libstrongswan.host_resolver.min_threads",
+                                                                        MIN_THREADS_DEFAULT));
+       this->max_threads = max(this->min_threads ?: 1,
+                                                       lib->settings->get_int(lib->settings,
+                                                                       "libstrongswan.host_resolver.max_threads",
+                                                                        MAX_THREADS_DEFAULT));
        return &this->public;
 }
index 855e3fe..f7b8c7e 100644 (file)
@@ -54,9 +54,7 @@ struct host_resolver_t {
 
 /**
  * Create a host_resolver_t instance.
- *
- * @param max_threads  maximum number of resolver threads to use
  */
-host_resolver_t *host_resolver_create(u_int max_threads);
+host_resolver_t *host_resolver_create();
 
 #endif /** HOST_RESOLVER_H_ @}*/
index b85ebea..a42d68c 100644 (file)
@@ -27,7 +27,6 @@
 #include <selectors/traffic_selector.h>
 
 #define CHECKSUM_LIBRARY IPSEC_LIB_DIR"/libchecksum.so"
-#define HOST_RESOLVER_MAX_THREADS 2
 
 typedef struct private_library_t private_library_t;
 
@@ -184,8 +183,8 @@ bool library_init(char *settings)
 
        this->objects = hashtable_create((hashtable_hash_t)hash,
                                                                         (hashtable_equals_t)equals, 4);
-       this->public.hosts = host_resolver_create(HOST_RESOLVER_MAX_THREADS);
        this->public.settings = settings_create(settings);
+       this->public.hosts = host_resolver_create();
        this->public.proposal = proposal_keywords_create();
        this->public.crypto = crypto_factory_create();
        this->public.creds = credential_factory_create();