root/maint/gnulib/tests/test-pthread_sigmask2.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. killer_thread_func
  2. sigint_handler
  3. main
  4. main

   1 /* Test of pthread_sigmask in a multi-threaded program.
   2    Copyright (C) 2011-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program 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
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Bruno Haible <bruno@clisp.org>, 2011.  */
  18 
  19 #include <config.h>
  20 
  21 #include <signal.h>
  22 
  23 #include <errno.h>
  24 #include <pthread.h>
  25 #include <stdio.h>
  26 #include <unistd.h>
  27 
  28 #include "macros.h"
  29 
  30 #if USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS
  31 
  32 static pthread_t main_thread;
  33 static pthread_t killer_thread;
  34 
  35 static void *
  36 killer_thread_func (void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  37 {
  38   sleep (1);
  39   pthread_kill (main_thread, SIGINT);
  40   return NULL;
  41 }
  42 
  43 static volatile int sigint_occurred;
  44 
  45 static void
  46 sigint_handler (int sig)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48   sigint_occurred++;
  49 }
  50 
  51 int
  52 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
  53 {
  54   sigset_t set;
  55 
  56   signal (SIGINT, sigint_handler);
  57 
  58   sigemptyset (&set);
  59   sigaddset (&set, SIGINT);
  60 
  61   /* Check error handling.  */
  62   /* This call returns 0 on NetBSD 8.0.  */
  63 #if !defined __NetBSD__
  64   ASSERT (pthread_sigmask (1729, &set, NULL) == EINVAL);
  65 #endif
  66 
  67   /* Block SIGINT.  */
  68   ASSERT (pthread_sigmask (SIG_BLOCK, &set, NULL) == 0);
  69 
  70   /* Request a SIGINT signal from another thread.  */
  71   main_thread = pthread_self ();
  72   ASSERT (pthread_create (&killer_thread, NULL, killer_thread_func, NULL) == 0);
  73 
  74   /* Wait.  */
  75   sleep (2);
  76 
  77   /* The signal should not have arrived yet, because it is blocked.  */
  78   ASSERT (sigint_occurred == 0);
  79 
  80   /* Unblock SIGINT.  */
  81   ASSERT (pthread_sigmask (SIG_UNBLOCK, &set, NULL) == 0);
  82 
  83   /* The signal should have arrived now, because POSIX says
  84        "If there are any pending unblocked signals after the call to
  85         pthread_sigmask(), at least one of those signals shall be delivered
  86         before the call to pthread_sigmask() returns."  */
  87   ASSERT (sigint_occurred == 1);
  88 
  89   /* Clean up the thread.  This avoid a "ThreadSanitizer: thread leak" warning
  90      from "gcc -fsanitize=thread".  */
  91   ASSERT (pthread_join (killer_thread, NULL) == 0);
  92 
  93   return 0;
  94 }
  95 
  96 #else
  97 
  98 int
  99 main ()
     /* [previous][next][first][last][top][bottom][index][help] */
 100 {
 101   fputs ("Skipping test: POSIX threads not enabled\n", stderr);
 102   return 77;
 103 }
 104 
 105 #endif

/* [previous][next][first][last][top][bottom][index][help] */