#include "pth_p.h"
struct pth_keytab_st {
int used;
void (*destructor)(void *);
};
static struct pth_keytab_st pth_keytab[PTH_KEY_MAX];
int pth_key_create(pth_key_t *key, void (*func)(void *))
{
for ((*key) = 0; (*key) < PTH_KEY_MAX; (*key)++) {
if (pth_keytab[(*key)].used == FALSE) {
pth_keytab[(*key)].used = TRUE;
pth_keytab[(*key)].destructor = func;
return TRUE;
}
}
return_errno(FALSE, EAGAIN);
}
int pth_key_delete(pth_key_t key)
{
if (key >= PTH_KEY_MAX)
return_errno(FALSE, EINVAL);
if (!pth_keytab[key].used)
return_errno(FALSE, EINVAL);
pth_keytab[key].used = FALSE;
return TRUE;
}
int pth_key_setdata(pth_key_t key, const void *value)
{
if (key >= PTH_KEY_MAX)
return_errno(FALSE, EINVAL);
if (!pth_keytab[key].used)
return_errno(FALSE, EINVAL);
if (pth_current->data_value == NULL) {
pth_current->data_value = (const void **)calloc(1, sizeof(void *)*PTH_KEY_MAX);
if (pth_current->data_value == NULL)
return_errno(FALSE, ENOMEM);
}
if (pth_current->data_value[key] == NULL) {
if (value != NULL)
pth_current->data_count++;
}
else {
if (value == NULL)
pth_current->data_count--;
}
pth_current->data_value[key] = value;
return TRUE;
}
void *pth_key_getdata(pth_key_t key)
{
if (key >= PTH_KEY_MAX)
return_errno(NULL, EINVAL);
if (!pth_keytab[key].used)
return_errno(NULL, EINVAL);
if (pth_current->data_value == NULL)
return NULL;
return (void *)pth_current->data_value[key];
}
intern void pth_key_destroydata(pth_t t)
{
void *data;
int key;
int itr;
void (*destructor)(void *);
if (t == NULL)
return;
if (t->data_value == NULL)
return;
for (itr = 0; itr < PTH_DESTRUCTOR_ITERATIONS; itr++) {
for (key = 0; key < PTH_KEY_MAX; key++) {
if (t->data_count > 0) {
destructor = NULL;
data = NULL;
if (pth_keytab[key].used) {
if (t->data_value[key] != NULL) {
data = (void *)t->data_value[key];
t->data_value[key] = NULL;
t->data_count--;
destructor = pth_keytab[key].destructor;
}
}
if (destructor != NULL)
destructor(data);
}
if (t->data_count == 0)
break;
}
if (t->data_count == 0)
break;
}
free(t->data_value);
t->data_value = NULL;
return;
}