(root)/
glibc-2.38/
sysdeps/
pthread/
tst-kill2.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 <signal.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  #include <sys/time.h>
      24  
      25  
      26  static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
      27  static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
      28  static pthread_barrier_t b;
      29  
      30  static void *
      31  tf (void *a)
      32  {
      33    /* Block SIGUSR1.  */
      34    sigset_t ss;
      35  
      36    sigemptyset (&ss);
      37    sigaddset (&ss, SIGUSR1);
      38    if (pthread_sigmask (SIG_BLOCK, &ss, NULL) != 0)
      39      {
      40        puts ("child: sigmask failed");
      41        exit (1);
      42      }
      43  
      44    if (pthread_mutex_lock (&m) != 0)
      45      {
      46        puts ("child: mutex_lock failed");
      47        exit (1);
      48      }
      49  
      50    int e = pthread_barrier_wait (&b);
      51    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
      52      {
      53        puts ("child: barrier_wait failed");
      54        exit (1);
      55      }
      56  
      57    /* Compute timeout.  */
      58    struct timeval tv;
      59    (void) gettimeofday (&tv, NULL);
      60    struct timespec ts;
      61    TIMEVAL_TO_TIMESPEC (&tv, &ts);
      62    /* Timeout: 1sec.  */
      63    ts.tv_sec += 1;
      64  
      65    /* This call should never return.  */
      66    if (pthread_cond_timedwait (&c, &m, &ts) != ETIMEDOUT)
      67      {
      68        puts ("cond_timedwait didn't time out");
      69        exit (1);
      70      }
      71  
      72    return NULL;
      73  }
      74  
      75  
      76  int
      77  do_test (void)
      78  {
      79    pthread_t th;
      80  
      81    if (pthread_barrier_init (&b, NULL, 2) != 0)
      82      {
      83        puts ("barrier_init failed");
      84        exit (1);
      85      }
      86  
      87    if (pthread_create (&th, NULL, tf, NULL) != 0)
      88      {
      89        puts ("create failed");
      90        exit (1);
      91      }
      92  
      93    int e = pthread_barrier_wait (&b);
      94    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
      95      {
      96        puts ("barrier_wait failed");
      97        exit (1);
      98      }
      99  
     100    if (pthread_mutex_lock (&m) != 0)
     101      {
     102        puts ("mutex_lock failed");
     103        exit (1);
     104      }
     105  
     106    /* Send the thread a signal which it has blocked.  */
     107    if (pthread_kill (th, SIGUSR1) != 0)
     108      {
     109        puts ("kill failed");
     110        exit (1);
     111      }
     112  
     113    if (pthread_mutex_unlock (&m) != 0)
     114      {
     115        puts ("mutex_unlock failed");
     116        exit (1);
     117      }
     118  
     119    void *r;
     120    if (pthread_join (th, &r) != 0)
     121      {
     122        puts ("join failed");
     123        exit (1);
     124      }
     125    if (r != NULL)
     126      {
     127        puts ("return value wrong");
     128        exit (1);
     129      }
     130  
     131    return 0;
     132  }
     133  
     134  
     135  #define TEST_FUNCTION do_test ()
     136  #include "../test-skeleton.c"