root/lib/pthread_sigmask.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pthread_sigmask

     1 /* POSIX compatible signal blocking for threads.
     2    Copyright (C) 2011-2023 Free Software Foundation, Inc.
     3 
     4    This file is free software: you can redistribute it and/or modify
     5    it under the terms of the GNU Lesser General Public License as
     6    published by the Free Software Foundation; either version 2.1 of the
     7    License, or (at your option) any later version.
     8 
     9    This file 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 Lesser General Public License for more details.
    13 
    14    You should have received a copy of the GNU Lesser General Public License
    15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
    16 
    17 #include <config.h>
    18 
    19 /* Specification.  */
    20 #include <signal.h>
    21 
    22 #include <errno.h>
    23 #include <stddef.h>
    24 
    25 #if PTHREAD_SIGMASK_INEFFECTIVE
    26 # include <string.h>
    27 #endif
    28 
    29 #if PTHREAD_SIGMASK_UNBLOCK_BUG
    30 # include <unistd.h>
    31 #endif
    32 
    33 int
    34 pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask)
    35 #undef pthread_sigmask
    36 {
    37 #if HAVE_PTHREAD_SIGMASK
    38   int ret;
    39 
    40 # if PTHREAD_SIGMASK_INEFFECTIVE
    41   sigset_t omask, omask_copy;
    42   sigset_t *old_mask_ptr = &omask;
    43   sigemptyset (&omask);
    44   /* Add a signal unlikely to be blocked, so that OMASK_COPY
    45      is unlikely to match the actual mask.  */
    46   sigaddset (&omask, SIGILL);
    47   memcpy (&omask_copy, &omask, sizeof omask);
    48 # else
    49   sigset_t *old_mask_ptr = old_mask;
    50 # endif
    51 
    52   ret = pthread_sigmask (how, new_mask, old_mask_ptr);
    53 
    54 # if PTHREAD_SIGMASK_INEFFECTIVE
    55   if (ret == 0)
    56     {
    57       /* Detect whether pthread_sigmask is currently ineffective.
    58          Don't cache the information: libpthread.so could be dynamically
    59          loaded after the program started and after pthread_sigmask was
    60          called for the first time.  */
    61       if (memcmp (&omask_copy, &omask, sizeof omask) == 0
    62           && pthread_sigmask (1729, &omask_copy, NULL) == 0)
    63         {
    64           /* pthread_sigmask is currently ineffective.  The program is not
    65              linked to -lpthread.  So use sigprocmask instead.  */
    66           return (sigprocmask (how, new_mask, old_mask) < 0 ? errno : 0);
    67         }
    68 
    69       if (old_mask)
    70         memcpy (old_mask, &omask, sizeof omask);
    71     }
    72 # endif
    73 # if PTHREAD_SIGMASK_FAILS_WITH_ERRNO
    74   if (ret == -1)
    75     return errno;
    76 # endif
    77 # if PTHREAD_SIGMASK_UNBLOCK_BUG
    78   if (ret == 0
    79       && new_mask != NULL
    80       && (how == SIG_UNBLOCK || how == SIG_SETMASK))
    81     {
    82       /* Give the OS the opportunity to raise signals that were pending before
    83          the pthread_sigmask call and have now been unblocked.  */
    84       usleep (1);
    85     }
    86 # endif
    87   return ret;
    88 #else
    89   int ret = sigprocmask (how, new_mask, old_mask);
    90   return (ret < 0 ? errno : 0);
    91 #endif
    92 }

/* [<][>][^][v][top][bottom][index][help] */