1 #include "pthread_impl.h" 2 3 volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX; 4 void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 }; 5 6 static void (*keys[PTHREAD_KEYS_MAX])(void *); 7 8 static pthread_rwlock_t key_lock = PTHREAD_RWLOCK_INITIALIZER; 9 10 static pthread_key_t next_key; 11 nodtor(void * dummy)12static void nodtor(void *dummy) 13 { 14 } 15 dummy_0(void)16static void dummy_0(void) 17 { 18 } 19 20 weak_alias(dummy_0, __tl_lock); 21 weak_alias(dummy_0, __tl_unlock); 22 __pthread_key_create(pthread_key_t * k,void (* dtor)(void *))23int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *)) 24 { 25 pthread_t self = __pthread_self(); 26 27 /* This can only happen in the main thread before 28 * pthread_create has been called. */ 29 if (!self->tsd) self->tsd = __pthread_tsd_main; 30 31 /* Purely a sentinel value since null means slot is free. */ 32 if (!dtor) dtor = nodtor; 33 34 __pthread_rwlock_wrlock(&key_lock); 35 pthread_key_t j = next_key; 36 do { 37 if (!keys[j]) { 38 keys[next_key = *k = j] = dtor; 39 __pthread_rwlock_unlock(&key_lock); 40 return 0; 41 } 42 } while ((j=(j+1)%PTHREAD_KEYS_MAX) != next_key); 43 44 __pthread_rwlock_unlock(&key_lock); 45 return EAGAIN; 46 } 47 __pthread_key_delete(pthread_key_t k)48int __pthread_key_delete(pthread_key_t k) 49 { 50 sigset_t set; 51 pthread_t self = __pthread_self(), td=self; 52 53 __block_app_sigs(&set); 54 __pthread_rwlock_wrlock(&key_lock); 55 56 __tl_lock(); 57 do td->tsd[k] = 0; 58 while ((td=td->next)!=self); 59 __tl_unlock(); 60 61 keys[k] = 0; 62 63 __pthread_rwlock_unlock(&key_lock); 64 __restore_sigs(&set); 65 66 return 0; 67 } 68 __pthread_tsd_run_dtors()69void __pthread_tsd_run_dtors() 70 { 71 pthread_t self = __pthread_self(); 72 int i, j; 73 for (j=0; self->tsd_used && j<PTHREAD_DESTRUCTOR_ITERATIONS; j++) { 74 __pthread_rwlock_rdlock(&key_lock); 75 self->tsd_used = 0; 76 for (i=0; i<PTHREAD_KEYS_MAX; i++) { 77 void *val = self->tsd[i]; 78 void (*dtor)(void *) = keys[i]; 79 self->tsd[i] = 0; 80 if (val && dtor && dtor != nodtor) { 81 __pthread_rwlock_unlock(&key_lock); 82 dtor(val); 83 __pthread_rwlock_rdlock(&key_lock); 84 } 85 } 86 __pthread_rwlock_unlock(&key_lock); 87 } 88 } 89 90 weak_alias(__pthread_key_create, pthread_key_create); 91 weak_alias(__pthread_key_delete, pthread_key_delete); 92