Home | History | Annotate | Download | only in tests
      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