parallelized trust chain verification
temporary imported certificates are thread-local only read-write locking on credential manager credential sets must be thread-save now
This commit is contained in:
@@ -47,15 +47,20 @@ struct private_credential_manager_t {
|
|||||||
*/
|
*/
|
||||||
linked_list_t *sets;
|
linked_list_t *sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* thread local set of credentials, linked_list_t with credential_set_t's
|
||||||
|
*/
|
||||||
|
pthread_key_t local_sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* trust relationship and certificate cache
|
* trust relationship and certificate cache
|
||||||
*/
|
*/
|
||||||
cert_cache_t *cache;
|
cert_cache_t *cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mutex to gain exclusive access
|
* read-write lock to sets list
|
||||||
*/
|
*/
|
||||||
mutex_t *mutex;
|
pthread_rwlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** data to pass to create_private_enumerator */
|
/** data to pass to create_private_enumerator */
|
||||||
@@ -89,12 +94,75 @@ typedef struct {
|
|||||||
identification_t *other;
|
identification_t *other;
|
||||||
} shared_data_t;
|
} shared_data_t;
|
||||||
|
|
||||||
|
/** enumerator over local and global sets */
|
||||||
|
typedef struct {
|
||||||
|
/** implements enumerator_t */
|
||||||
|
enumerator_t public;
|
||||||
|
/** enumerator over global sets */
|
||||||
|
enumerator_t *global;
|
||||||
|
/** enumerator over local sets */
|
||||||
|
enumerator_t *local;
|
||||||
|
} sets_enumerator_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destroy a sets_enumerator_t
|
||||||
|
*/
|
||||||
|
static void sets_enumerator_destroy(sets_enumerator_t *this)
|
||||||
|
{
|
||||||
|
DESTROY_IF(this->global);
|
||||||
|
DESTROY_IF(this->local);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets_enumerator_t.enumerate
|
||||||
|
*/
|
||||||
|
static bool sets_enumerator_enumerate(sets_enumerator_t *this,
|
||||||
|
credential_set_t **set)
|
||||||
|
{
|
||||||
|
if (this->global)
|
||||||
|
{
|
||||||
|
if (this->global->enumerate(this->global, set))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
/* end of global sets, look for local */
|
||||||
|
this->global->destroy(this->global);
|
||||||
|
this->global = NULL;
|
||||||
|
}
|
||||||
|
if (this->local)
|
||||||
|
{
|
||||||
|
return this->local->enumerate(this->local, set);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create an enumerator over both, global and local sets
|
||||||
|
*/
|
||||||
|
static enumerator_t *create_sets_enumerator(private_credential_manager_t *this)
|
||||||
|
{
|
||||||
|
linked_list_t *local;
|
||||||
|
sets_enumerator_t *enumerator = malloc_thing(sets_enumerator_t);
|
||||||
|
|
||||||
|
enumerator->public.enumerate = (void*)sets_enumerator_enumerate;
|
||||||
|
enumerator->public.destroy = (void*)sets_enumerator_destroy;
|
||||||
|
enumerator->global = this->sets->create_enumerator(this->sets);
|
||||||
|
enumerator->local = NULL;
|
||||||
|
local = pthread_getspecific(this->local_sets);
|
||||||
|
if (local)
|
||||||
|
{
|
||||||
|
enumerator->local = local->create_enumerator(local);
|
||||||
|
}
|
||||||
|
return &enumerator->public;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cleanup function for cert data
|
* cleanup function for cert data
|
||||||
*/
|
*/
|
||||||
static void destroy_cert_data(cert_data_t *data)
|
static void destroy_cert_data(cert_data_t *data)
|
||||||
{
|
{
|
||||||
data->this->mutex->unlock(data->this->mutex);
|
pthread_rwlock_unlock(&data->this->lock);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,8 +189,8 @@ static enumerator_t *create_cert_enumerator(private_credential_manager_t *this,
|
|||||||
data->id = id;
|
data->id = id;
|
||||||
data->trusted = trusted;
|
data->trusted = trusted;
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
pthread_rwlock_rdlock(&this->lock);
|
||||||
return enumerator_create_nested(this->sets->create_enumerator(this->sets),
|
return enumerator_create_nested(create_sets_enumerator(this),
|
||||||
(void*)create_cert, data,
|
(void*)create_cert, data,
|
||||||
(void*)destroy_cert_data);
|
(void*)destroy_cert_data);
|
||||||
}
|
}
|
||||||
@@ -137,7 +205,6 @@ static certificate_t *get_cert(private_credential_manager_t *this,
|
|||||||
certificate_t *current, *found = NULL;
|
certificate_t *current, *found = NULL;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
|
||||||
enumerator = create_cert_enumerator(this, cert, key, id, trusted);
|
enumerator = create_cert_enumerator(this, cert, key, id, trusted);
|
||||||
if (enumerator->enumerate(enumerator, ¤t))
|
if (enumerator->enumerate(enumerator, ¤t))
|
||||||
{
|
{
|
||||||
@@ -145,7 +212,6 @@ static certificate_t *get_cert(private_credential_manager_t *this,
|
|||||||
found = current->get_ref(current);
|
found = current->get_ref(current);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
this->mutex->unlock(this->mutex);
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +221,7 @@ static certificate_t *get_cert(private_credential_manager_t *this,
|
|||||||
*/
|
*/
|
||||||
static void destroy_cdp_data(cdp_data_t *data)
|
static void destroy_cdp_data(cdp_data_t *data)
|
||||||
{
|
{
|
||||||
data->this->mutex->unlock(data->this->mutex);
|
pthread_rwlock_unlock(&data->this->lock);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,8 +243,8 @@ static enumerator_t * create_cdp_enumerator(private_credential_manager_t *this,
|
|||||||
data->type = type;
|
data->type = type;
|
||||||
data->id = id;
|
data->id = id;
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
pthread_rwlock_rdlock(&this->lock);
|
||||||
return enumerator_create_nested(this->sets->create_enumerator(this->sets),
|
return enumerator_create_nested(create_sets_enumerator(this),
|
||||||
(void*)create_cdp, data,
|
(void*)create_cdp, data,
|
||||||
(void*)destroy_cdp_data);
|
(void*)destroy_cdp_data);
|
||||||
}
|
}
|
||||||
@@ -188,7 +254,7 @@ static enumerator_t * create_cdp_enumerator(private_credential_manager_t *this,
|
|||||||
*/
|
*/
|
||||||
static void destroy_private_data(private_data_t *data)
|
static void destroy_private_data(private_data_t *data)
|
||||||
{
|
{
|
||||||
data->this->mutex->unlock(data->this->mutex);
|
pthread_rwlock_unlock(&data->this->lock);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,9 +279,10 @@ static enumerator_t* create_private_enumerator(
|
|||||||
data->this = this;
|
data->this = this;
|
||||||
data->type = key;
|
data->type = key;
|
||||||
data->keyid = keyid;
|
data->keyid = keyid;
|
||||||
this->mutex->lock(this->mutex);
|
pthread_rwlock_rdlock(&this->lock);
|
||||||
return enumerator_create_nested(this->sets->create_enumerator(this->sets),
|
return enumerator_create_nested(create_sets_enumerator(this),
|
||||||
(void*)create_private, data, (void*)destroy_private_data);
|
(void*)create_private, data,
|
||||||
|
(void*)destroy_private_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -241,7 +308,7 @@ static private_key_t *get_private_by_keyid(private_credential_manager_t *this,
|
|||||||
*/
|
*/
|
||||||
static void destroy_shared_data(shared_data_t *data)
|
static void destroy_shared_data(shared_data_t *data)
|
||||||
{
|
{
|
||||||
data->this->mutex->unlock(data->this->mutex);
|
pthread_rwlock_unlock(&data->this->lock);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,8 +333,8 @@ static enumerator_t *create_shared_enumerator(private_credential_manager_t *this
|
|||||||
data->me = me;
|
data->me = me;
|
||||||
data->other = other;
|
data->other = other;
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
pthread_rwlock_rdlock(&this->lock);
|
||||||
return enumerator_create_nested(this->sets->create_enumerator(this->sets),
|
return enumerator_create_nested(create_sets_enumerator(this),
|
||||||
(void*)create_shared, data,
|
(void*)create_shared, data,
|
||||||
(void*)destroy_shared_data);
|
(void*)destroy_shared_data);
|
||||||
}
|
}
|
||||||
@@ -300,12 +367,41 @@ static shared_key_t *get_shared(private_credential_manager_t *this,
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a credential set to the thread local list
|
||||||
|
*/
|
||||||
|
static void add_local_set(private_credential_manager_t *this,
|
||||||
|
credential_set_t *set)
|
||||||
|
{
|
||||||
|
linked_list_t *sets;
|
||||||
|
|
||||||
|
sets = pthread_getspecific(this->local_sets);
|
||||||
|
if (!sets)
|
||||||
|
{ /* first invocation */
|
||||||
|
sets = linked_list_create();
|
||||||
|
pthread_setspecific(this->local_sets, sets);
|
||||||
|
}
|
||||||
|
sets->insert_last(sets, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a credential set from the thread local list
|
||||||
|
*/
|
||||||
|
static void remove_local_set(private_credential_manager_t *this,
|
||||||
|
credential_set_t *set)
|
||||||
|
{
|
||||||
|
linked_list_t *sets;
|
||||||
|
|
||||||
|
sets = pthread_getspecific(this->local_sets);
|
||||||
|
sets->remove(sets, set, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* forward declaration
|
* forward declaration
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
|
static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
|
||||||
key_type_t type, identification_t *id, bool crl, bool ocsp);
|
key_type_t type, identification_t *id, bool crl, bool ocsp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do an OCSP request
|
* Do an OCSP request
|
||||||
*/
|
*/
|
||||||
@@ -366,7 +462,7 @@ static bool verify_ocsp(private_credential_manager_t *this,
|
|||||||
bool verified = FALSE;
|
bool verified = FALSE;
|
||||||
|
|
||||||
wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response);
|
wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response);
|
||||||
this->sets->insert_last(this->sets, wrapper);
|
add_local_set(this, &wrapper->set);
|
||||||
|
|
||||||
subject = &response->certificate;
|
subject = &response->certificate;
|
||||||
responder = subject->get_issuer(subject);
|
responder = subject->get_issuer(subject);
|
||||||
@@ -383,7 +479,7 @@ static bool verify_ocsp(private_credential_manager_t *this,
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
this->sets->remove(this->sets, wrapper, NULL);
|
remove_local_set(this, &wrapper->set);
|
||||||
wrapper->destroy(wrapper);
|
wrapper->destroy(wrapper);
|
||||||
return verified;
|
return verified;
|
||||||
}
|
}
|
||||||
@@ -1125,10 +1221,10 @@ static void public_destroy(public_enumerator_t *this)
|
|||||||
this->inner->destroy(this->inner);
|
this->inner->destroy(this->inner);
|
||||||
if (this->wrapper)
|
if (this->wrapper)
|
||||||
{
|
{
|
||||||
this->this->sets->remove(this->this->sets, this->wrapper, NULL);
|
remove_local_set(this->this, &this->wrapper->set);
|
||||||
this->wrapper->destroy(this->wrapper);
|
this->wrapper->destroy(this->wrapper);
|
||||||
}
|
}
|
||||||
this->this->mutex->unlock(this->this->mutex);
|
pthread_rwlock_unlock(&this->this->lock);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1146,12 +1242,12 @@ static enumerator_t* create_public_enumerator(private_credential_manager_t *this
|
|||||||
enumerator->this = this;
|
enumerator->this = this;
|
||||||
enumerator->current = NULL;
|
enumerator->current = NULL;
|
||||||
enumerator->wrapper = NULL;
|
enumerator->wrapper = NULL;
|
||||||
this->mutex->lock(this->mutex);
|
|
||||||
if (auth)
|
if (auth)
|
||||||
{
|
{
|
||||||
enumerator->wrapper = auth_info_wrapper_create(auth);
|
enumerator->wrapper = auth_info_wrapper_create(auth);
|
||||||
this->sets->insert_last(this->sets, enumerator->wrapper);
|
add_local_set(this, &enumerator->wrapper->set);
|
||||||
}
|
}
|
||||||
|
pthread_rwlock_rdlock(&this->lock);
|
||||||
return &enumerator->public;
|
return &enumerator->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1295,7 +1391,6 @@ static private_key_t *get_private(private_credential_manager_t *this,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
|
||||||
/* try to build a trustchain for each certificate found */
|
/* try to build a trustchain for each certificate found */
|
||||||
enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
|
enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
|
||||||
while (enumerator->enumerate(enumerator, &cert))
|
while (enumerator->enumerate(enumerator, &cert))
|
||||||
@@ -1330,7 +1425,6 @@ static private_key_t *get_private(private_credential_manager_t *this,
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
this->mutex->unlock(this->mutex);
|
|
||||||
return private;
|
return private;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1340,9 +1434,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
|
|||||||
static void flush_cache(private_credential_manager_t *this,
|
static void flush_cache(private_credential_manager_t *this,
|
||||||
certificate_type_t type)
|
certificate_type_t type)
|
||||||
{
|
{
|
||||||
this->mutex->lock(this->mutex);
|
|
||||||
this->cache->flush(this->cache, type);
|
this->cache->flush(this->cache, type);
|
||||||
this->mutex->unlock(this->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1351,18 +1443,19 @@ static void flush_cache(private_credential_manager_t *this,
|
|||||||
static void add_set(private_credential_manager_t *this,
|
static void add_set(private_credential_manager_t *this,
|
||||||
credential_set_t *set)
|
credential_set_t *set)
|
||||||
{
|
{
|
||||||
this->mutex->lock(this->mutex);
|
pthread_rwlock_wrlock(&this->lock);
|
||||||
this->sets->insert_last(this->sets, set);
|
this->sets->insert_last(this->sets, set);
|
||||||
this->mutex->unlock(this->mutex);
|
pthread_rwlock_unlock(&this->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of credential_manager_t.remove_set.
|
* Implementation of credential_manager_t.remove_set.
|
||||||
*/
|
*/
|
||||||
static void remove_set(private_credential_manager_t *this, credential_set_t *set)
|
static void remove_set(private_credential_manager_t *this, credential_set_t *set)
|
||||||
{
|
{
|
||||||
this->mutex->lock(this->mutex);
|
pthread_rwlock_wrlock(&this->lock);
|
||||||
this->sets->remove(this->sets, set, NULL);
|
this->sets->remove(this->sets, set, NULL);
|
||||||
this->mutex->unlock(this->mutex);
|
pthread_rwlock_unlock(&this->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1372,8 +1465,9 @@ static void destroy(private_credential_manager_t *this)
|
|||||||
{
|
{
|
||||||
this->sets->remove(this->sets, this->cache, NULL);
|
this->sets->remove(this->sets, this->cache, NULL);
|
||||||
this->sets->destroy(this->sets);
|
this->sets->destroy(this->sets);
|
||||||
|
pthread_key_delete(this->local_sets);
|
||||||
this->cache->destroy(this->cache);
|
this->cache->destroy(this->cache);
|
||||||
this->mutex->destroy(this->mutex);
|
pthread_rwlock_destroy(&this->lock);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1397,9 +1491,10 @@ credential_manager_t *credential_manager_create()
|
|||||||
this->public.destroy = (void(*)(credential_manager_t*))destroy;
|
this->public.destroy = (void(*)(credential_manager_t*))destroy;
|
||||||
|
|
||||||
this->sets = linked_list_create();
|
this->sets = linked_list_create();
|
||||||
|
pthread_key_create(&this->local_sets, (void*)this->sets->destroy);
|
||||||
this->cache = cert_cache_create();
|
this->cache = cert_cache_create();
|
||||||
this->sets->insert_first(this->sets, this->cache);
|
this->sets->insert_first(this->sets, this->cache);
|
||||||
this->mutex = mutex_create(MUTEX_RECURSIVE);
|
pthread_rwlock_init(&this->lock, NULL);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,9 +63,8 @@ typedef struct credential_manager_t credential_manager_t;
|
|||||||
|
|
||||||
@endverbatim
|
@endverbatim
|
||||||
*
|
*
|
||||||
* Synchronization is done completely in the manager, so the sets don't have
|
* The credential manager uses rwlocks for performance reasons, credential
|
||||||
* to worry about it. The locking mechanism is reentrant save, so sets can
|
* sets must be fully thread save.
|
||||||
* call the manager.
|
|
||||||
*/
|
*/
|
||||||
struct credential_manager_t {
|
struct credential_manager_t {
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
|
#include <utils/mutex.h>
|
||||||
|
|
||||||
#define CACHE_SIZE 30
|
#define CACHE_SIZE 30
|
||||||
|
|
||||||
@@ -49,6 +50,11 @@ struct private_cert_cache_t {
|
|||||||
* have we increased the cache without a check_cache?
|
* have we increased the cache without a check_cache?
|
||||||
*/
|
*/
|
||||||
bool check_required;
|
bool check_required;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mutex to lock relations list
|
||||||
|
*/
|
||||||
|
mutex_t *mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,6 +121,7 @@ static bool issued_by(private_cert_cache_t *this,
|
|||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
/* lookup cache */
|
/* lookup cache */
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
enumerator = this->relations->create_enumerator(this->relations);
|
enumerator = this->relations->create_enumerator(this->relations);
|
||||||
while (enumerator->enumerate(enumerator, ¤t))
|
while (enumerator->enumerate(enumerator, ¤t))
|
||||||
{
|
{
|
||||||
@@ -139,6 +146,7 @@ static bool issued_by(private_cert_cache_t *this,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -153,8 +161,10 @@ static bool issued_by(private_cert_cache_t *this,
|
|||||||
found->subject = subject->get_ref(subject);
|
found->subject = subject->get_ref(subject);
|
||||||
found->issuer = issuer->get_ref(issuer);
|
found->issuer = issuer->get_ref(issuer);
|
||||||
found->last_use = time(NULL);
|
found->last_use = time(NULL);
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
this->relations->insert_last(this->relations, found);
|
this->relations->insert_last(this->relations, found);
|
||||||
check_cache(this);
|
check_cache(this);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +235,7 @@ static void certs_destroy(cert_data_t *data)
|
|||||||
{
|
{
|
||||||
check_cache(data->this);
|
check_cache(data->this);
|
||||||
}
|
}
|
||||||
|
data->this->mutex->unlock(data->this->mutex);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,8 +257,9 @@ static enumerator_t *create_enumerator(private_cert_cache_t *this,
|
|||||||
data->key = key;
|
data->key = key;
|
||||||
data->id = id;
|
data->id = id;
|
||||||
data->this = this;
|
data->this = this;
|
||||||
this->enumerating++;
|
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
|
this->enumerating++;
|
||||||
return enumerator_create_filter(
|
return enumerator_create_filter(
|
||||||
this->relations->create_enumerator(this->relations),
|
this->relations->create_enumerator(this->relations),
|
||||||
(void*)certs_filter, data, (void*)certs_destroy);
|
(void*)certs_filter, data, (void*)certs_destroy);
|
||||||
@@ -261,6 +273,7 @@ static void flush(private_cert_cache_t *this, certificate_type_t type)
|
|||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
relation_t *relation;
|
relation_t *relation;
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
enumerator = this->relations->create_enumerator(this->relations);
|
enumerator = this->relations->create_enumerator(this->relations);
|
||||||
while (enumerator->enumerate(enumerator, &relation))
|
while (enumerator->enumerate(enumerator, &relation))
|
||||||
{
|
{
|
||||||
@@ -272,6 +285,7 @@ static void flush(private_cert_cache_t *this, certificate_type_t type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -280,6 +294,7 @@ static void flush(private_cert_cache_t *this, certificate_type_t type)
|
|||||||
static void destroy(private_cert_cache_t *this)
|
static void destroy(private_cert_cache_t *this)
|
||||||
{
|
{
|
||||||
this->relations->destroy_function(this->relations, (void*)relation_destroy);
|
this->relations->destroy_function(this->relations, (void*)relation_destroy);
|
||||||
|
this->mutex->destroy(this->mutex);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,6 +316,7 @@ cert_cache_t *cert_cache_create()
|
|||||||
this->relations = linked_list_create();
|
this->relations = linked_list_create();
|
||||||
this->enumerating = FALSE;
|
this->enumerating = FALSE;
|
||||||
this->check_required = FALSE;
|
this->check_required = FALSE;
|
||||||
|
this->mutex = mutex_create(MUTEX_RECURSIVE);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user