(root)/
glibc-2.38/
sysdeps/
pthread/
tst-cancel22.c
       1  /* Copyright (C) 2003-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <pthread.h>
      20  #include <stdio.h>
      21  #include <stdlib.h>
      22  #include <unistd.h>
      23  
      24  pthread_barrier_t b;
      25  int seen;
      26  
      27  static void *
      28  tf (void *arg)
      29  {
      30    int old;
      31    int r = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &old);
      32    if (r != 0)
      33      {
      34        puts ("setcancelstate failed");
      35        exit (1);
      36      }
      37  
      38    r = pthread_barrier_wait (&b);
      39    if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
      40      {
      41        puts ("barrier_wait failed");
      42        exit (1);
      43      }
      44  
      45    for (int i = 0; i < 10; ++i)
      46      {
      47        struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
      48        TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
      49      }
      50  
      51    seen = 1;
      52    pthread_setcancelstate (old, NULL);
      53  
      54    struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
      55    TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
      56  
      57    exit (1);
      58  }
      59  
      60  
      61  static int
      62  do_test (void)
      63  {
      64    if (pthread_barrier_init (&b, NULL, 2) != 0)
      65     {
      66       puts ("barrier init failed");
      67       return 1;
      68     }
      69  
      70    pthread_t th;
      71    if (pthread_create (&th, NULL, tf, NULL) != 0)
      72      {
      73        puts ("thread creation failed");
      74        return 1;
      75      }
      76  
      77    int r = pthread_barrier_wait (&b);
      78    if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
      79      {
      80        puts ("barrier_wait failed");
      81        return 1;
      82      }
      83  
      84    if (pthread_cancel (th) != 0)
      85      {
      86        puts ("cancel failed");
      87        return 1;
      88      }
      89  
      90    void *status;
      91    if (pthread_join (th, &status) != 0)
      92      {
      93        puts ("join failed");
      94        return 1;
      95      }
      96    if (status != PTHREAD_CANCELED)
      97      {
      98        puts ("thread not canceled");
      99        return 1;
     100      }
     101  
     102    if (pthread_barrier_destroy (&b) != 0)
     103      {
     104        puts ("barrier_destroy failed");
     105        return 1;
     106      }
     107  
     108    if (seen != 1)
     109      {
     110        puts ("thread cancelled when PTHREAD_CANCEL_DISABLED");
     111        return 1;
     112      }
     113  
     114    return 0;
     115  }
     116  
     117  #define TEST_FUNCTION do_test ()
     118  #include "../test-skeleton.c"