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