Terminate unused resolver threads after a timeout
This commit is contained in:
@@ -696,6 +696,12 @@ strength
|
|||||||
.BR libstrongswan.ecp_x_coordinate_only " [yes]"
|
.BR libstrongswan.ecp_x_coordinate_only " [yes]"
|
||||||
Compliance with the errata for RFC 4753
|
Compliance with the errata for RFC 4753
|
||||||
.TP
|
.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]"
|
.BR libstrongswan.integrity_test " [no]"
|
||||||
Check daemon, libstrongswan and plugin integrity at startup
|
Check daemon, libstrongswan and plugin integrity at startup
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
@@ -27,6 +27,17 @@
|
|||||||
#include <utils/hashtable.h>
|
#include <utils/hashtable.h>
|
||||||
#include <utils/linked_list.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;
|
typedef struct private_host_resolver_t private_host_resolver_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,6 +70,11 @@ struct private_host_resolver_t {
|
|||||||
*/
|
*/
|
||||||
condvar_t *new_query;
|
condvar_t *new_query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum number of resolver threads
|
||||||
|
*/
|
||||||
|
u_int min_threads;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of resolver threads
|
* Maximum number of resolver threads
|
||||||
*/
|
*/
|
||||||
@@ -142,15 +158,22 @@ static job_requeue_t resolve_hosts(private_host_resolver_t *this)
|
|||||||
struct addrinfo hints, *result;
|
struct addrinfo hints, *result;
|
||||||
query_t *query;
|
query_t *query;
|
||||||
int error;
|
int error;
|
||||||
bool old;
|
bool old, timed_out;
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
this->mutex->lock(this->mutex);
|
||||||
while (this->queue->remove_first(this->queue, (void**)&query) != SUCCESS)
|
while (this->queue->remove_first(this->queue, (void**)&query) != SUCCESS)
|
||||||
{
|
{
|
||||||
thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
|
thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
|
||||||
old = thread_cancelability(TRUE);
|
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);
|
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);
|
thread_cleanup_pop(FALSE);
|
||||||
}
|
}
|
||||||
this->busy_threads++;
|
this->busy_threads++;
|
||||||
@@ -275,7 +298,7 @@ METHOD(host_resolver_t, destroy, void,
|
|||||||
/*
|
/*
|
||||||
* Described in header
|
* Described in header
|
||||||
*/
|
*/
|
||||||
host_resolver_t *host_resolver_create(u_int max_threads)
|
host_resolver_t *host_resolver_create()
|
||||||
{
|
{
|
||||||
private_host_resolver_t *this;
|
private_host_resolver_t *this;
|
||||||
|
|
||||||
@@ -290,8 +313,14 @@ host_resolver_t *host_resolver_create(u_int max_threads)
|
|||||||
.queue = linked_list_create(),
|
.queue = linked_list_create(),
|
||||||
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||||
.new_query = condvar_create(CONDVAR_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;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,7 @@ struct host_resolver_t {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a host_resolver_t instance.
|
* 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_ @}*/
|
#endif /** HOST_RESOLVER_H_ @}*/
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#include <selectors/traffic_selector.h>
|
#include <selectors/traffic_selector.h>
|
||||||
|
|
||||||
#define CHECKSUM_LIBRARY IPSEC_LIB_DIR"/libchecksum.so"
|
#define CHECKSUM_LIBRARY IPSEC_LIB_DIR"/libchecksum.so"
|
||||||
#define HOST_RESOLVER_MAX_THREADS 2
|
|
||||||
|
|
||||||
typedef struct private_library_t private_library_t;
|
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,
|
this->objects = hashtable_create((hashtable_hash_t)hash,
|
||||||
(hashtable_equals_t)equals, 4);
|
(hashtable_equals_t)equals, 4);
|
||||||
this->public.hosts = host_resolver_create(HOST_RESOLVER_MAX_THREADS);
|
|
||||||
this->public.settings = settings_create(settings);
|
this->public.settings = settings_create(settings);
|
||||||
|
this->public.hosts = host_resolver_create();
|
||||||
this->public.proposal = proposal_keywords_create();
|
this->public.proposal = proposal_keywords_create();
|
||||||
this->public.crypto = crypto_factory_create();
|
this->public.crypto = crypto_factory_create();
|
||||||
this->public.creds = credential_factory_create();
|
this->public.creds = credential_factory_create();
|
||||||
|
|||||||
Reference in New Issue
Block a user