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