diff --git a/tests/pthread/tls.c b/tests/pthread/tls.c index ab79f8b8c9..21a4a614c8 100644 --- a/tests/pthread/tls.c +++ b/tests/pthread/tls.c @@ -1,13 +1,12 @@ #include -// PTHREAD_KEYS_MAX +// PTHREAD_KEYS_MAX, PTHREAD_DESTRUCTOR_ITERATIONS #include #include #include #include #include -pthread_key_t key_a; -pthread_key_t key_b; +pthread_key_t key_a, key_b, key_c, key_d, key_e; size_t total_destructor_runs = 0; void drop_key_a(void *val_a) { @@ -48,16 +47,46 @@ void drop_key_b(void *val_b) { } } +void drop_unreachable(void *val_c) { + // Should never be called. + (void)val_c; + assert(false); +} + +void drop_key_d(void *val_d) { + assert(pthread_getspecific(key_d) == NULL && val_d == (void *)0xdddd); + // [`pthread_key_{create,setspecific,getspecific,delete}`] can still be used + // inside the destructor itself. + printf("drop_key_d(d=%p)\n", val_d); + pthread_key_t key_g; + assert(!pthread_key_create(&key_g, drop_unreachable)); + assert(!pthread_setspecific(key_g, &key_g)); + assert(pthread_getspecific(key_g) == &key_g); + assert(!pthread_key_delete(key_g)); +} + void *test_tls_destructors(void *arg) { (void)arg; assert(!pthread_key_create(&key_a, drop_key_a)); assert(!pthread_key_create(&key_b, drop_key_b)); + assert(!pthread_key_create(&key_c, drop_unreachable)); + assert(!pthread_key_create(&key_d, drop_key_d)); + assert(!pthread_key_create(&key_e, drop_unreachable)); assert(!pthread_setspecific(key_a, (void *)0xaaaa)); assert(!pthread_setspecific(key_b, (void *)0xbbbb)); + assert(!pthread_setspecific(key_c, (void *)0xcccc)); + assert(!pthread_setspecific(key_d, (void *)0xdddd)); + assert(!pthread_key_delete(key_c)); return NULL; } int main(void) { + pthread_key_t key_f; + assert(!pthread_key_create(&key_f, NULL)); + assert(!pthread_setspecific(key_f, &key_f)); + assert(pthread_getspecific(key_f) == &key_f); + assert(!pthread_key_delete(key_f)); + pthread_t t1; assert(!pthread_create(&t1, NULL, test_tls_destructors, NULL)); assert(!pthread_join(t1, NULL)); @@ -66,6 +95,5 @@ int main(void) { // of iterations will be `2 * PTHREAD_DESTRUCTOR_ITERATIONS`. assert((total_destructor_runs / 2) == PTHREAD_DESTRUCTOR_ITERATIONS); - assert(pthread_getspecific(PTHREAD_KEYS_MAX) == NULL); return EXIT_SUCCESS; }