shunt-manager: Add a lock to safely access the list of shunt policies

This commit is contained in:
Tobias Brunner
2015-07-27 13:50:52 +02:00
parent 12b3cdba76
commit f3d39666e0
+17 -3
View File
@@ -1,4 +1,5 @@
/* /*
* Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2011 Andreas Steffen * Copyright (C) 2011 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@@ -20,7 +21,6 @@
#include <threading/rwlock.h> #include <threading/rwlock.h>
#include <collections/linked_list.h> #include <collections/linked_list.h>
typedef struct private_shunt_manager_t private_shunt_manager_t; typedef struct private_shunt_manager_t private_shunt_manager_t;
/** /**
@@ -37,6 +37,11 @@ struct private_shunt_manager_t {
* Installed shunts, as child_cfg_t * Installed shunts, as child_cfg_t
*/ */
linked_list_t *shunts; linked_list_t *shunts;
/**
* Lock to safely access the list of shunts
*/
rwlock_t *lock;
}; };
/** /**
@@ -120,6 +125,7 @@ METHOD(shunt_manager_t, install, bool,
bool found = FALSE; bool found = FALSE;
/* check if not already installed */ /* check if not already installed */
this->lock->write_lock(this->lock);
enumerator = this->shunts->create_enumerator(this->shunts); enumerator = this->shunts->create_enumerator(this->shunts);
while (enumerator->enumerate(enumerator, &child_cfg)) while (enumerator->enumerate(enumerator, &child_cfg))
{ {
@@ -130,14 +136,15 @@ METHOD(shunt_manager_t, install, bool,
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (found) if (found)
{ {
DBG1(DBG_CFG, "shunt %N policy '%s' already installed", DBG1(DBG_CFG, "shunt %N policy '%s' already installed",
ipsec_mode_names, child->get_mode(child), child->get_name(child)); ipsec_mode_names, child->get_mode(child), child->get_name(child));
this->lock->unlock(this->lock);
return TRUE; return TRUE;
} }
this->shunts->insert_last(this->shunts, child->get_ref(child)); this->shunts->insert_last(this->shunts, child->get_ref(child));
this->lock->unlock(this->lock);
return install_shunt_policy(child); return install_shunt_policy(child);
} }
@@ -215,6 +222,7 @@ METHOD(shunt_manager_t, uninstall, bool,
enumerator_t *enumerator; enumerator_t *enumerator;
child_cfg_t *child, *found = NULL; child_cfg_t *child, *found = NULL;
this->lock->write_lock(this->lock);
enumerator = this->shunts->create_enumerator(this->shunts); enumerator = this->shunts->create_enumerator(this->shunts);
while (enumerator->enumerate(enumerator, &child)) while (enumerator->enumerate(enumerator, &child))
{ {
@@ -226,6 +234,7 @@ METHOD(shunt_manager_t, uninstall, bool,
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
if (!found) if (!found)
{ {
@@ -239,7 +248,10 @@ METHOD(shunt_manager_t, uninstall, bool,
METHOD(shunt_manager_t, create_enumerator, enumerator_t*, METHOD(shunt_manager_t, create_enumerator, enumerator_t*,
private_shunt_manager_t *this) private_shunt_manager_t *this)
{ {
return this->shunts->create_enumerator(this->shunts); this->lock->read_lock(this->lock);
return enumerator_create_cleaner(
this->shunts->create_enumerator(this->shunts),
(void*)this->lock->unlock, this->lock);
} }
METHOD(shunt_manager_t, destroy, void, METHOD(shunt_manager_t, destroy, void,
@@ -253,6 +265,7 @@ METHOD(shunt_manager_t, destroy, void,
child->destroy(child); child->destroy(child);
} }
this->shunts->destroy(this->shunts); this->shunts->destroy(this->shunts);
this->lock->destroy(this->lock);
free(this); free(this);
} }
@@ -271,6 +284,7 @@ shunt_manager_t *shunt_manager_create()
.destroy = _destroy, .destroy = _destroy,
}, },
.shunts = linked_list_create(), .shunts = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
); );
return &this->public; return &this->public;