(root)/
glibc-2.38/
sysdeps/
pthread/
tst-cancel25.c
       1  #include <pthread.h>
       2  #include <signal.h>
       3  #include <stdio.h>
       4  #include <stdlib.h>
       5  #include <internal-signals.h>
       6  
       7  
       8  static pthread_barrier_t b;
       9  static pthread_t th2;
      10  
      11  
      12  static void *
      13  tf2 (void *arg)
      14  {
      15    sigset_t mask;
      16    if (pthread_sigmask (SIG_SETMASK, NULL, &mask) != 0)
      17      {
      18        puts ("pthread_sigmask failed");
      19        exit (1);
      20      }
      21  #ifdef SIGCANCEL
      22    if (sigismember (&mask, SIGCANCEL))
      23      {
      24        puts ("SIGCANCEL blocked in new thread");
      25        exit (1);
      26      }
      27  #endif
      28  
      29    /* Sync with the main thread so that we do not test anything else.  */
      30    int e = pthread_barrier_wait (&b);
      31    if (e != 0  && e != PTHREAD_BARRIER_SERIAL_THREAD)
      32      {
      33        puts ("barrier_wait failed");
      34        exit (1);
      35      }
      36  
      37    while (1)
      38      {
      39        /* Just a cancelable call.  */
      40        struct timespec ts = { 10000, 0 };
      41        nanosleep (&ts, 0);
      42      }
      43  
      44    return NULL;
      45  }
      46  
      47  
      48  static void
      49  unwhand (void *arg)
      50  {
      51    if (pthread_create (&th2, NULL, tf2, NULL) != 0)
      52      {
      53        puts ("unwhand: create failed");
      54        exit (1);
      55      }
      56  }
      57  
      58  
      59  static void *
      60  tf (void *arg)
      61  {
      62    pthread_cleanup_push (unwhand, NULL);
      63  
      64    /* Sync with the main thread so that we do not test anything else.  */
      65    int e = pthread_barrier_wait (&b);
      66    if (e != 0  && e != PTHREAD_BARRIER_SERIAL_THREAD)
      67      {
      68        puts ("barrier_wait failed");
      69        exit (1);
      70      }
      71  
      72    while (1)
      73      {
      74        /* Just a cancelable call.  */
      75        struct timespec ts = { 10000, 0 };
      76        nanosleep (&ts, 0);
      77      }
      78  
      79    pthread_cleanup_pop (0);
      80  
      81    return NULL;
      82  }
      83  
      84  
      85  static int
      86  do_test (void)
      87  {
      88    if (pthread_barrier_init (&b, NULL, 2) != 0)
      89      {
      90        puts ("barrier_init failed");
      91        return 1;
      92      }
      93  
      94    pthread_t th1;
      95    if (pthread_create (&th1, NULL, tf, NULL) != 0)
      96      {
      97        puts ("create failed");
      98        return 1;
      99      }
     100  
     101    int e = pthread_barrier_wait (&b);
     102    if (e != 0  && e != PTHREAD_BARRIER_SERIAL_THREAD)
     103      {
     104        puts ("barrier_wait failed");
     105        return 1;
     106      }
     107  
     108    /* Make sure tf1 enters nanosleep.  */
     109    struct timespec ts = { 0, 500000000 };
     110    while (nanosleep (&ts, &ts) != 0)
     111      ;
     112  
     113    if (pthread_cancel (th1) != 0)
     114      {
     115        puts ("1st cancel failed");
     116        return 1;
     117      }
     118  
     119    void *res;
     120    if (pthread_join (th1, &res) != 0)
     121      {
     122        puts ("1st join failed");
     123        return 1;
     124      }
     125    if (res != PTHREAD_CANCELED)
     126      {
     127        puts ("1st thread not canceled");
     128        return 1;
     129      }
     130  
     131    e = pthread_barrier_wait (&b);
     132    if (e != 0  && e != PTHREAD_BARRIER_SERIAL_THREAD)
     133      {
     134        puts ("barrier_wait failed");
     135        return 1;
     136      }
     137  
     138    /* Make sure tf2 enters nanosleep.  */
     139    ts.tv_sec = 0;
     140    ts.tv_nsec = 500000000;
     141    while (nanosleep (&ts, &ts) != 0)
     142      ;
     143  
     144    puts ("calling pthread_cancel the second time");
     145    if (pthread_cancel (th2) != 0)
     146      {
     147        puts ("2nd cancel failed");
     148        return 1;
     149      }
     150  
     151    puts ("calling pthread_join the second time");
     152    if (pthread_join (th2, &res) != 0)
     153      {
     154        puts ("2nd join failed");
     155        return 1;
     156      }
     157    if (res != PTHREAD_CANCELED)
     158      {
     159        puts ("2nd thread not canceled");
     160        return 1;
     161      }
     162  
     163    if (pthread_barrier_destroy (&b) != 0)
     164      {
     165        puts ("barrier_destroy failed");
     166        return 0;
     167      }
     168  
     169    return 0;
     170  }
     171  
     172  #define TEST_FUNCTION do_test ()
     173  #include "../test-skeleton.c"