1 #include "pthread_impl.h"
4 volatile size_t __pthread_tsd_size
= sizeof(void *) * PTHREAD_KEYS_MAX
;
5 void *__pthread_tsd_main
[PTHREAD_KEYS_MAX
] = { 0 };
7 static void (*keys
[PTHREAD_KEYS_MAX
])(void *);
9 static pthread_rwlock_t key_lock
= PTHREAD_RWLOCK_INITIALIZER
;
11 static pthread_key_t next_key
;
13 static void nodtor(void *dummy
)
17 static void dummy_0(void)
21 weak_alias(dummy_0
, __tl_lock
);
22 weak_alias(dummy_0
, __tl_unlock
);
24 void __pthread_key_atfork(int who
)
26 if (who
<0) __pthread_rwlock_rdlock(&key_lock
);
27 else if (!who
) __pthread_rwlock_unlock(&key_lock
);
28 else key_lock
= (pthread_rwlock_t
)PTHREAD_RWLOCK_INITIALIZER
;
31 int __pthread_key_create(pthread_key_t
*k
, void (*dtor
)(void *))
33 pthread_t self
= __pthread_self();
35 /* This can only happen in the main thread before
36 * pthread_create has been called. */
37 if (!self
->tsd
) self
->tsd
= __pthread_tsd_main
;
39 /* Purely a sentinel value since null means slot is free. */
40 if (!dtor
) dtor
= nodtor
;
42 __pthread_rwlock_wrlock(&key_lock
);
43 pthread_key_t j
= next_key
;
46 keys
[next_key
= *k
= j
] = dtor
;
47 __pthread_rwlock_unlock(&key_lock
);
50 } while ((j
=(j
+1)%PTHREAD_KEYS_MAX
) != next_key
);
52 __pthread_rwlock_unlock(&key_lock
);
56 int __pthread_key_delete(pthread_key_t k
)
59 pthread_t self
= __pthread_self(), td
=self
;
61 __block_app_sigs(&set
);
62 __pthread_rwlock_wrlock(&key_lock
);
66 while ((td
=td
->next
)!=self
);
71 __pthread_rwlock_unlock(&key_lock
);
77 void __pthread_tsd_run_dtors()
79 pthread_t self
= __pthread_self();
81 for (j
=0; self
->tsd_used
&& j
<PTHREAD_DESTRUCTOR_ITERATIONS
; j
++) {
82 __pthread_rwlock_rdlock(&key_lock
);
84 for (i
=0; i
<PTHREAD_KEYS_MAX
; i
++) {
85 void *val
= self
->tsd
[i
];
86 void (*dtor
)(void *) = keys
[i
];
88 if (val
&& dtor
&& dtor
!= nodtor
) {
89 __pthread_rwlock_unlock(&key_lock
);
91 __pthread_rwlock_rdlock(&key_lock
);
94 __pthread_rwlock_unlock(&key_lock
);
98 weak_alias(__pthread_key_create
, pthread_key_create
);
99 weak_alias(__pthread_key_delete
, pthread_key_delete
);