Home | History | Annotate | Download | only in tests
      1 /**
      2  * Test whether detached threads are handled properly.
      3  * This test program is based on pth_detached.c, with the difference that
      4  * in this test program the main thread uses a counting semaphore instead
      5  * of a counter protected by a mutex to wait until all detached threads
      6  * finished.
      7  */
      8 
      9 
     10 #include <assert.h>
     11 #include <pthread.h>
     12 #include <semaphore.h>
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include <unistd.h>
     16 
     17 
     18 static sem_t s_sem;
     19 
     20 
     21 static void increment_finished_count()
     22 {
     23   sem_post(&s_sem);
     24 }
     25 
     26 static void* thread_func1(void* arg)
     27 {
     28   write(STDOUT_FILENO, ".", 1);
     29   increment_finished_count();
     30   return 0;
     31 }
     32 
     33 static void* thread_func2(void* arg)
     34 {
     35   pthread_detach(pthread_self());
     36   write(STDOUT_FILENO, ".", 1);
     37   increment_finished_count();
     38   return 0;
     39 }
     40 
     41 int main(int argc, char** argv)
     42 {
     43   const int count1 = argc > 1 ? atoi(argv[1]) : 100;
     44   const int count2 = argc > 2 ? atoi(argv[2]) : 100;
     45   int thread_arg[count1 > count2 ? count1 : count2];
     46   int i;
     47   int detachstate;
     48   pthread_attr_t attr;
     49 
     50   for (i = 0; i < count1 || i < count2; i++)
     51     thread_arg[i] = i;
     52 
     53   sem_init(&s_sem, 0, 0);
     54 
     55   pthread_attr_init(&attr);
     56   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
     57   assert(pthread_attr_getdetachstate(&attr, &detachstate) == 0);
     58   assert(detachstate == PTHREAD_CREATE_DETACHED);
     59   pthread_attr_setstacksize(&attr, 16384);
     60   // Create count1 detached threads by setting the "detached" property via
     61   // thread attributes.
     62   for (i = 0; i < count1; i++)
     63   {
     64     pthread_t thread;
     65     pthread_create(&thread, &attr, thread_func1, &thread_arg[i]);
     66   }
     67   // Create count2 detached threads by letting the threads detach themselves.
     68   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
     69   assert(pthread_attr_getdetachstate(&attr, &detachstate) == 0);
     70   assert(detachstate == PTHREAD_CREATE_JOINABLE);
     71   for (i = 0; i < count2; i++)
     72   {
     73     pthread_t thread;
     74     pthread_create(&thread, &attr, thread_func2, &thread_arg[i]);
     75   }
     76   pthread_attr_destroy(&attr);
     77 
     78   // Wait until all detached threads have written their output to stdout.
     79   for (i = 0; i < count1 + count2; i++)
     80   {
     81     sem_wait(&s_sem);
     82   }
     83 
     84   write(STDOUT_FILENO, "\n", 1);
     85   fprintf(stderr, "Done.\n");
     86 
     87   sem_destroy(&s_sem);
     88 
     89   return 0;
     90 }
     91