1// commit: fb11b6b85e1e01daf17228be32d7f98b47517363 2011-02-19 2// pthread_exit should call dtors (even in the last thread) 3#include <stdlib.h> 4#include <string.h> 5#include <errno.h> 6#include <pthread.h> 7#include <sys/wait.h> 8#include <unistd.h> 9#include "test.h" 10 11#define TEST(r, f) if (((r)=(f))) t_error(#f " failed: %s\n", strerror(r)) 12#define TESTC(c, m) ( (c) || (t_error("%s failed (" m ")\n", #c), 0) ) 13 14static pthread_key_t k; 15static int data; 16 17static void dtor(void *p) 18{ 19 *(int *)p = 1; 20} 21 22static void *start(void *arg) 23{ 24 if (pthread_setspecific(k, arg)) 25 return arg; 26 return 0; 27} 28 29static void cleanup(void) 30{ 31 TESTC(data == 1, "dtor was not run for the last thread"); 32 _exit(t_status); 33} 34 35static void die(void) 36{ 37 _exit(1); 38} 39 40int main(void) 41{ 42 pthread_t td; 43 int r, arg=0, pid; 44 void *res; 45 46 // test if atexit handlers are run after pthread_exit 47 // (early musl failed this test) 48 pid = fork(); 49 switch (pid) { 50 case -1: 51 t_error("fork failed: %s\n", strerror(errno)); 52 return 1; 53 case 0: 54 atexit(die); 55 pthread_exit(0); 56 default: 57 if (waitpid(pid, &r, 0) != pid) { 58 t_error("waitpid failed: %s\n", strerror(errno)); 59 return 1; 60 } 61 if (!WIFEXITED(r) || WEXITSTATUS(r) != 1) { 62 t_error("atexit handler was not run after last thread exited" 63 " (exited=%d, signal=%d, status=%d, want exit status=1)\n", 64 WIFEXITED(r), !WIFEXITED(r)&&WIFSIGNALED(r)?WTERMSIG(r):0, WIFEXITED(r)?WEXITSTATUS(r):0); 65 return 1; 66 } 67 } 68 69 // dtor should set tsd (arg and data) from 0 to 1 70 if (atexit(cleanup)) { 71 t_error("atexit failed\n"); 72 return 1; 73 } 74 TEST(r, pthread_key_create(&k, dtor)); 75 TEST(r, pthread_setspecific(k, &data)); 76 TEST(r, pthread_create(&td, 0, start, &arg)); 77 TEST(r, pthread_join(td, &res)); 78 TESTC(res == 0, "pthread_setspecific failed in thread"); 79 TESTC(arg == 1, "dtor failed to run"); 80 TESTC(data == 0, "tsd in main thread is corrupted"); 81 TESTC(pthread_getspecific(k) == &data, "tsd in main thread is corrupted"); 82 pthread_exit(0); 83} 84