#include <collections/linked_list.h>
#include <threading/rwlock.h>
+#define TKM_LIMIT 100
+
ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_DH,
"NONCE_CONTEXT",
"DH_CONTEXT");
tkm_id_manager_t public;
/**
- * Next free context id values.
- */
- int nextids[TKM_CTX_MAX];
-
- /**
- * Per-kind list of acquired context ids
+ * Per-kind array of free context ids
*/
- linked_list_t *ctxids[TKM_CTX_MAX];
+ bool* ctxids[TKM_CTX_MAX];
/**
* rwlocks for context id lists
METHOD(tkm_id_manager_t, acquire_id, int,
private_tkm_id_manager_t * const this, const tkm_context_kind_t kind)
{
- int *current;
- int id = 0;
+ int j, id = 0;
if (!is_valid_kind(kind))
{
}
this->locks[kind]->write_lock(this->locks[kind]);
-
- id = this->nextids[kind];
- current = malloc(sizeof(int));
- *current = id;
- this->ctxids[kind]->insert_last(this->ctxids[kind], current);
- this->nextids[kind]++;
-
+ for (j = 0; j < TKM_LIMIT; j++)
+ {
+ if (this->ctxids[kind][j])
+ {
+ this->ctxids[kind][j] = false;
+ id = j + 1;
+ break;
+ }
+ }
this->locks[kind]->unlock(this->locks[kind]);
if (!id)
private_tkm_id_manager_t * const this, const tkm_context_kind_t kind,
const int id)
{
- enumerator_t *enumerator;
- int *current;
- bool found = FALSE;
+ const int idx = id - 1;
if (!is_valid_kind(kind))
{
}
this->locks[kind]->write_lock(this->locks[kind]);
- enumerator = this->ctxids[kind]->create_enumerator(this->ctxids[kind]);
- while (enumerator->enumerate(enumerator, ¤t))
- {
- if (*current == id)
- {
- this->ctxids[kind]->remove_at(this->ctxids[kind], enumerator);
- found = TRUE;
- break;
- }
- }
- enumerator->destroy(enumerator);
+ this->ctxids[kind][idx] = true;
this->locks[kind]->unlock(this->locks[kind]);
- if (!found)
- {
- DBG3(DBG_LIB, "releasing non-existent %N context id %d, nothing to do",
- tkm_context_kind_names, kind, id);
- }
-
return TRUE;
}
private_tkm_id_manager_t *this)
{
int i;
-
for (i = 0; i < TKM_CTX_MAX; i++)
{
- this->ctxids[i]->destroy(this->ctxids[i]);
+ free(this->ctxids[i]);
this->locks[i]->destroy(this->locks[i]);
}
free(this);
tkm_id_manager_t *tkm_id_manager_create()
{
private_tkm_id_manager_t *this;
- int i;
+ int i, j;
INIT(this,
.public = {
for (i = 0; i < TKM_CTX_MAX; i++)
{
- this->nextids[i] = 1;
- this->ctxids[i] = linked_list_create();
+ this->ctxids[i] = malloc(TKM_LIMIT * sizeof(bool));
this->locks[i] = rwlock_create(RWLOCK_TYPE_DEFAULT);
+ for (j = 0; j < TKM_LIMIT; j++)
+ {
+ /* available id slots are in true state (is_available) */
+ this->ctxids[i][j] = true;
+ }
}
return &this->public;
}
END_TEST
+START_TEST(test_acquire_id_same)
+{
+ int id1 = 0, id2 = 0;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create();
+
+ id1 = idmgr->acquire_id(idmgr, TKM_CTX_NONCE);
+ fail_unless(id1 > 0, "Unable to acquire first id");
+
+ /* Acquire another id, must be different than first */
+ id2 = idmgr->acquire_id(idmgr, TKM_CTX_NONCE);
+ fail_unless(id2 > 0, "Unable to acquire second id");
+ fail_unless(id1 != id2, "Same id received twice");
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
START_TEST(test_release_id)
{
int i, id = 0;
tcase_add_test(tc, test_id_mgr_creation);
tcase_add_test(tc, test_acquire_id);
tcase_add_test(tc, test_acquire_id_invalid_kind);
+ tcase_add_test(tc, test_acquire_id_same);
tcase_add_test(tc, test_release_id);
tcase_add_test(tc, test_release_id_invalid_kind);
tcase_add_test(tc, test_release_id_nonexistent);