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