User Data
static int i = 0;
int counter()
{
return (++i);
}
int pthread_key_create(pthread_key_t * key, void (*destructor(void *)) );
int pthread_key_delete(pthread_key_t key);
int pthread_setspecific(pthread_key_t * key, const void *value)
void * pthread_getspecific(pthread_key_t * key)
static pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t counter_key;
static counter_init = 0;
int counter()
{
int *i;
P_M_L(&counter_mutex);
if (counter_init == 0) {
if (pthread_key_create(&counter_key, free)) {
counter_init = 1;
P_M_U(&counter_mutex);
exit(1);
}
}
P_M_U(&counter_mutex);
if ((i = pthread_getspecific(&counter_key)) == NULL)
i = malloc(sizeof(int));
pthread_setspecific(counter_key, &i)
}
return(++(*i));
}
int pthread_getspecific(pthread_key_t * key, void **)
void pthread_cleanup_push(void (*routine)(void *), void *arg); void pthread_cleanup_pop(int execute);Often inmpelemted as ...
struct _pthread_handler_rec {
};
#define pthread_cleanup_push(rtn, arg) { \
struct _pthread_handler_rec __cleanup_handler, **__head; \
__cleanup_handler.rtn = rtn; \
__cleanup_handler.arg = arg; \
head = pthread_getspecific(_pthread_handler_key); \
__cleanup_handler.next = *__head; \
*head = &__cleanup_handler;
#define pthread_cleanup_pop(ex) \
*__head = cleanup_handler.next; \
if (ex) cleanup_handler.rtn(__cleanup_handler.arg); \
}
extern void (*dest[])(void *);
void __pthread_cleanup(void)
{
int key, i;
void * data;
for (i = 0; i < PTHREAD_DESTRUCTOR_ITERATIONS; i++) {
for (key = 0; key < PTHREAD_KEYS_MAX; key++) {
if (data = pthread_getspecific(key) {
if (data) {
pthread_setspecific(key, NULL);
if (dest[key]) {
dest[key](data);
}
}
}
}
}
}