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); } } } } } }