1 /* Test whether detached threads are handled properly. */ 2 3 4 #include <assert.h> 5 #include <pthread.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <unistd.h> 9 10 11 static int s_finished_count; 12 static pthread_mutex_t s_mutex; 13 14 15 static void increment_finished_count() 16 { 17 pthread_mutex_lock(&s_mutex); 18 s_finished_count++; 19 pthread_mutex_unlock(&s_mutex); 20 } 21 22 static int get_finished_count() 23 { 24 int result; 25 pthread_mutex_lock(&s_mutex); 26 result = s_finished_count; 27 pthread_mutex_unlock(&s_mutex); 28 return result; 29 } 30 31 static void* thread_func1(void* arg) 32 { 33 write(STDOUT_FILENO, ".", 1); 34 increment_finished_count(); 35 return 0; 36 } 37 38 static void* thread_func2(void* arg) 39 { 40 pthread_detach(pthread_self()); 41 write(STDOUT_FILENO, ".", 1); 42 increment_finished_count(); 43 return 0; 44 } 45 46 int main(int argc, char** argv) 47 { 48 const int count1 = argc > 1 ? atoi(argv[1]) : 100; 49 const int count2 = argc > 2 ? atoi(argv[2]) : 100; 50 int thread_arg[count1 > count2 ? count1 : count2]; 51 int i; 52 int detachstate; 53 pthread_attr_t attr; 54 55 for (i = 0; i < count1 || i < count2; i++) 56 thread_arg[i] = i; 57 58 pthread_mutex_init(&s_mutex, 0); 59 60 pthread_attr_init(&attr); 61 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 62 assert(pthread_attr_getdetachstate(&attr, &detachstate) == 0); 63 assert(detachstate == PTHREAD_CREATE_DETACHED); 64 pthread_attr_setstacksize(&attr, 16384); 65 // Create count1 detached threads by setting the "detached" property via 66 // thread attributes. 67 for (i = 0; i < count1; i++) 68 { 69 pthread_t thread; 70 pthread_create(&thread, &attr, thread_func1, &thread_arg[i]); 71 } 72 // Create count2 detached threads by letting the threads detach themselves. 73 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 74 assert(pthread_attr_getdetachstate(&attr, &detachstate) == 0); 75 assert(detachstate == PTHREAD_CREATE_JOINABLE); 76 for (i = 0; i < count2; i++) 77 { 78 pthread_t thread; 79 pthread_create(&thread, &attr, thread_func2, &thread_arg[i]); 80 } 81 pthread_attr_destroy(&attr); 82 83 // Wait until all detached threads have written their output to stdout. 84 while (get_finished_count() < count1 + count2) 85 { 86 struct timespec delay = { 0, 1 * 1000 * 1000 }; 87 nanosleep(&delay, 0); 88 } 89 90 write(STDOUT_FILENO, "\n", 1); 91 92 pthread_mutex_destroy(&s_mutex); 93 94 sleep(1); 95 96 return 0; 97 } 98