| 1 | # pthread_sigmask.m4 serial 21
|
|---|
| 2 | dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
|
|---|
| 3 | dnl This file is free software; the Free Software Foundation
|
|---|
| 4 | dnl gives unlimited permission to copy and/or distribute it,
|
|---|
| 5 | dnl with or without modifications, as long as this notice is preserved.
|
|---|
| 6 |
|
|---|
| 7 | AC_DEFUN([gl_FUNC_PTHREAD_SIGMASK],
|
|---|
| 8 | [
|
|---|
| 9 | AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
|
|---|
| 10 |
|
|---|
| 11 | AC_CHECK_FUNCS_ONCE([pthread_sigmask])
|
|---|
| 12 |
|
|---|
| 13 | dnl On MinGW pthread_sigmask is just a macro which always returns 0.
|
|---|
| 14 | dnl It does not exist as a real function, which is required by POSIX.
|
|---|
| 15 | AC_CACHE_CHECK([whether pthread_sigmask is a macro],
|
|---|
| 16 | [gl_cv_func_pthread_sigmask_macro],
|
|---|
| 17 | [AC_EGREP_CPP([headers_define_pthread_sigmask], [
|
|---|
| 18 | #include <pthread.h>
|
|---|
| 19 | #include <signal.h>
|
|---|
| 20 | #ifdef pthread_sigmask
|
|---|
| 21 | headers_define_pthread_sigmask
|
|---|
| 22 | #endif],
|
|---|
| 23 | [gl_cv_func_pthread_sigmask_macro=yes],
|
|---|
| 24 | [gl_cv_func_pthread_sigmask_macro=no])
|
|---|
| 25 | ])
|
|---|
| 26 |
|
|---|
| 27 | LIB_PTHREAD_SIGMASK=
|
|---|
| 28 |
|
|---|
| 29 | if test $gl_cv_func_pthread_sigmask_macro = yes; then
|
|---|
| 30 | dnl pthread_sigmask is a dummy macro.
|
|---|
| 31 | HAVE_PTHREAD_SIGMASK=0
|
|---|
| 32 | dnl Make sure to '#undef pthread_sigmask' before defining it.
|
|---|
| 33 | REPLACE_PTHREAD_SIGMASK=1
|
|---|
| 34 | else
|
|---|
| 35 | dnl Test whether the gnulib module 'threadlib' is in use.
|
|---|
| 36 | dnl Some packages like Emacs use --avoid=threadlib.
|
|---|
| 37 | dnl Write the symbol in such a way that it does not cause 'aclocal' to pick
|
|---|
| 38 | dnl the threadlib.m4 file that is installed in $PREFIX/share/aclocal/.
|
|---|
| 39 | m4_ifdef([gl_][THREADLIB], [
|
|---|
| 40 | AC_REQUIRE([gl_][THREADLIB])
|
|---|
| 41 |
|
|---|
| 42 | if test "$gl_threads_api" = posix; then
|
|---|
| 43 | if test $ac_cv_func_pthread_sigmask = yes; then
|
|---|
| 44 | dnl pthread_sigmask is available without -lpthread.
|
|---|
| 45 | :
|
|---|
| 46 | else
|
|---|
| 47 | if test -n "$LIBMULTITHREAD"; then
|
|---|
| 48 | AC_CACHE_CHECK([for pthread_sigmask in $LIBMULTITHREAD],
|
|---|
| 49 | [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD],
|
|---|
| 50 | [gl_save_LIBS="$LIBS"
|
|---|
| 51 | LIBS="$LIBS $LIBMULTITHREAD"
|
|---|
| 52 | AC_LINK_IFELSE(
|
|---|
| 53 | [AC_LANG_PROGRAM(
|
|---|
| 54 | [[#include <pthread.h>
|
|---|
| 55 | #include <signal.h>
|
|---|
| 56 | ]],
|
|---|
| 57 | [[return pthread_sigmask (0, (sigset_t *) 0, (sigset_t *) 0);]])
|
|---|
| 58 | ],
|
|---|
| 59 | [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD=yes],
|
|---|
| 60 | [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD=no])
|
|---|
| 61 | LIBS="$gl_save_LIBS"
|
|---|
| 62 | ])
|
|---|
| 63 | if test $gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD = yes; then
|
|---|
| 64 | dnl pthread_sigmask is available with -pthread or -lpthread.
|
|---|
| 65 | LIB_PTHREAD_SIGMASK="$LIBMULTITHREAD"
|
|---|
| 66 | else
|
|---|
| 67 | dnl pthread_sigmask is not available at all.
|
|---|
| 68 | HAVE_PTHREAD_SIGMASK=0
|
|---|
| 69 | fi
|
|---|
| 70 | else
|
|---|
| 71 | dnl pthread_sigmask is not available at all.
|
|---|
| 72 | HAVE_PTHREAD_SIGMASK=0
|
|---|
| 73 | fi
|
|---|
| 74 | fi
|
|---|
| 75 | else
|
|---|
| 76 | dnl pthread_sigmask may exist but does not interoperate with the chosen
|
|---|
| 77 | dnl multithreading facility.
|
|---|
| 78 | if test $ac_cv_func_pthread_sigmask = yes; then
|
|---|
| 79 | REPLACE_PTHREAD_SIGMASK=1
|
|---|
| 80 | else
|
|---|
| 81 | HAVE_PTHREAD_SIGMASK=0
|
|---|
| 82 | fi
|
|---|
| 83 | fi
|
|---|
| 84 | ], [
|
|---|
| 85 | dnl The module 'threadlib' is not in use, due to --avoid=threadlib being
|
|---|
| 86 | dnl specified.
|
|---|
| 87 | dnl The package either has prepared CPPFLAGS and LIBS for use of
|
|---|
| 88 | dnl POSIX:2008 threads, or wants to build single-threaded programs.
|
|---|
| 89 | if test $ac_cv_func_pthread_sigmask = yes; then
|
|---|
| 90 | dnl pthread_sigmask exists and does not require extra libraries.
|
|---|
| 91 | dnl Assume that it is declared.
|
|---|
| 92 | :
|
|---|
| 93 | else
|
|---|
| 94 | dnl pthread_sigmask either does not exist or needs extra libraries.
|
|---|
| 95 | HAVE_PTHREAD_SIGMASK=0
|
|---|
| 96 | dnl Define the symbol rpl_pthread_sigmask, not pthread_sigmask,
|
|---|
| 97 | dnl so as to not accidentally override the system's pthread_sigmask
|
|---|
| 98 | dnl symbol from libpthread. This is necessary on IRIX 6.5.
|
|---|
| 99 | REPLACE_PTHREAD_SIGMASK=1
|
|---|
| 100 | fi
|
|---|
| 101 | ])
|
|---|
| 102 | fi
|
|---|
| 103 |
|
|---|
| 104 | AC_SUBST([LIB_PTHREAD_SIGMASK])
|
|---|
| 105 | dnl We don't need a variable LTLIB_PTHREAD_SIGMASK, because when
|
|---|
| 106 | dnl "$gl_threads_api" = posix, $LTLIBMULTITHREAD and $LIBMULTITHREAD are the
|
|---|
| 107 | dnl same.
|
|---|
| 108 |
|
|---|
| 109 | dnl Now test for some bugs in the system function.
|
|---|
| 110 | if test $HAVE_PTHREAD_SIGMASK = 1; then
|
|---|
| 111 | AC_REQUIRE([AC_PROG_CC])
|
|---|
| 112 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
|---|
| 113 |
|
|---|
| 114 | dnl On FreeBSD 13.0, MidnightBSD 1.1, HP-UX 11.31, Solaris 9, in programs
|
|---|
| 115 | dnl that are not linked with -lpthread, the pthread_sigmask() function
|
|---|
| 116 | dnl always returns 0 and has no effect.
|
|---|
| 117 | if test -z "$LIB_PTHREAD_SIGMASK"; then
|
|---|
| 118 | case " $LIBS " in
|
|---|
| 119 | *' -pthread '*) ;;
|
|---|
| 120 | *' -lpthread '*) ;;
|
|---|
| 121 | *)
|
|---|
| 122 | AC_CACHE_CHECK([whether pthread_sigmask works without -lpthread],
|
|---|
| 123 | [gl_cv_func_pthread_sigmask_in_libc_works],
|
|---|
| 124 | [
|
|---|
| 125 | AC_RUN_IFELSE(
|
|---|
| 126 | [AC_LANG_SOURCE([[
|
|---|
| 127 | #include <pthread.h>
|
|---|
| 128 | #include <signal.h>
|
|---|
| 129 | #include <stddef.h>
|
|---|
| 130 | int main ()
|
|---|
| 131 | {
|
|---|
| 132 | sigset_t set;
|
|---|
| 133 | sigemptyset (&set);
|
|---|
| 134 | return pthread_sigmask (1729, &set, NULL) != 0;
|
|---|
| 135 | }]])],
|
|---|
| 136 | [gl_cv_func_pthread_sigmask_in_libc_works=no],
|
|---|
| 137 | [gl_cv_func_pthread_sigmask_in_libc_works=yes],
|
|---|
| 138 | [
|
|---|
| 139 | changequote(,)dnl
|
|---|
| 140 | case "$host_os" in
|
|---|
| 141 | freebsd* | midnightbsd* | hpux* | solaris | solaris2.[2-9]*)
|
|---|
| 142 | gl_cv_func_pthread_sigmask_in_libc_works="guessing no";;
|
|---|
| 143 | *)
|
|---|
| 144 | gl_cv_func_pthread_sigmask_in_libc_works="guessing yes";;
|
|---|
| 145 | esac
|
|---|
| 146 | changequote([,])dnl
|
|---|
| 147 | ])
|
|---|
| 148 | ])
|
|---|
| 149 | case "$gl_cv_func_pthread_sigmask_in_libc_works" in
|
|---|
| 150 | *no)
|
|---|
| 151 | REPLACE_PTHREAD_SIGMASK=1
|
|---|
| 152 | AC_DEFINE([PTHREAD_SIGMASK_INEFFECTIVE], [1],
|
|---|
| 153 | [Define to 1 if pthread_sigmask may return 0 and have no effect.])
|
|---|
| 154 | ;;
|
|---|
| 155 | esac;;
|
|---|
| 156 | esac
|
|---|
| 157 | fi
|
|---|
| 158 |
|
|---|
| 159 | dnl On Cygwin 1.7.5, the pthread_sigmask() has a wrong return value
|
|---|
| 160 | dnl convention: Upon failure, it returns -1 and sets errno.
|
|---|
| 161 | AC_CACHE_CHECK([whether pthread_sigmask returns error numbers],
|
|---|
| 162 | [gl_cv_func_pthread_sigmask_return_works],
|
|---|
| 163 | [
|
|---|
| 164 | gl_save_LIBS="$LIBS"
|
|---|
| 165 | LIBS="$LIBS $LIB_PTHREAD_SIGMASK"
|
|---|
| 166 | AC_RUN_IFELSE(
|
|---|
| 167 | [AC_LANG_SOURCE([[
|
|---|
| 168 | #include <pthread.h>
|
|---|
| 169 | #include <signal.h>
|
|---|
| 170 | #include <stddef.h>
|
|---|
| 171 | int main ()
|
|---|
| 172 | {
|
|---|
| 173 | sigset_t set;
|
|---|
| 174 | sigemptyset (&set);
|
|---|
| 175 | if (pthread_sigmask (1729, &set, NULL) == -1)
|
|---|
| 176 | return 1;
|
|---|
| 177 | return 0;
|
|---|
| 178 | }]])],
|
|---|
| 179 | [gl_cv_func_pthread_sigmask_return_works=yes],
|
|---|
| 180 | [gl_cv_func_pthread_sigmask_return_works=no],
|
|---|
| 181 | [case "$host_os" in
|
|---|
| 182 | cygwin*)
|
|---|
| 183 | gl_cv_func_pthread_sigmask_return_works="guessing no";;
|
|---|
| 184 | *)
|
|---|
| 185 | gl_cv_func_pthread_sigmask_return_works="guessing yes";;
|
|---|
| 186 | esac
|
|---|
| 187 | ])
|
|---|
| 188 | LIBS="$gl_save_LIBS"
|
|---|
| 189 | ])
|
|---|
| 190 | case "$gl_cv_func_pthread_sigmask_return_works" in
|
|---|
| 191 | *no)
|
|---|
| 192 | REPLACE_PTHREAD_SIGMASK=1
|
|---|
| 193 | AC_DEFINE([PTHREAD_SIGMASK_FAILS_WITH_ERRNO], [1],
|
|---|
| 194 | [Define to 1 if pthread_sigmask(), when it fails, returns -1 and sets errno.])
|
|---|
| 195 | ;;
|
|---|
| 196 | esac
|
|---|
| 197 |
|
|---|
| 198 | dnl On IRIX 6.5, in a single-threaded program, pending signals are not
|
|---|
| 199 | dnl immediately delivered when they are unblocked through pthread_sigmask,
|
|---|
| 200 | dnl only a little while later.
|
|---|
| 201 | AC_CACHE_CHECK([whether pthread_sigmask unblocks signals correctly],
|
|---|
| 202 | [gl_cv_func_pthread_sigmask_unblock_works],
|
|---|
| 203 | [
|
|---|
| 204 | case "$host_os" in
|
|---|
| 205 | irix*)
|
|---|
| 206 | gl_cv_func_pthread_sigmask_unblock_works="guessing no";;
|
|---|
| 207 | *)
|
|---|
| 208 | gl_cv_func_pthread_sigmask_unblock_works="guessing yes";;
|
|---|
| 209 | esac
|
|---|
| 210 | m4_ifdef([gl_][THREADLIB],
|
|---|
| 211 | [dnl Link against $LIBMULTITHREAD, not only $LIB_PTHREAD_SIGMASK.
|
|---|
| 212 | dnl Otherwise we get a false positive on those platforms where
|
|---|
| 213 | dnl $gl_cv_func_pthread_sigmask_in_libc_works is "no".
|
|---|
| 214 | gl_save_LIBS=$LIBS
|
|---|
| 215 | LIBS="$LIBS $LIBMULTITHREAD"])
|
|---|
| 216 | AC_RUN_IFELSE(
|
|---|
| 217 | [AC_LANG_SOURCE([[
|
|---|
| 218 | #include <pthread.h>
|
|---|
| 219 | #include <signal.h>
|
|---|
| 220 | #include <stdio.h>
|
|---|
| 221 | #include <stdlib.h>
|
|---|
| 222 | #include <unistd.h>
|
|---|
| 223 | ]GL_MDA_DEFINES[
|
|---|
| 224 | static volatile int sigint_occurred;
|
|---|
| 225 | static void
|
|---|
| 226 | sigint_handler (int sig)
|
|---|
| 227 | {
|
|---|
| 228 | sigint_occurred++;
|
|---|
| 229 | }
|
|---|
| 230 | int main ()
|
|---|
| 231 | {
|
|---|
| 232 | sigset_t set;
|
|---|
| 233 | int pid = getpid ();
|
|---|
| 234 | char command[80];
|
|---|
| 235 | signal (SIGINT, sigint_handler);
|
|---|
| 236 | sigemptyset (&set);
|
|---|
| 237 | sigaddset (&set, SIGINT);
|
|---|
| 238 | if (!(pthread_sigmask (SIG_BLOCK, &set, NULL) == 0))
|
|---|
| 239 | return 1;
|
|---|
| 240 | sprintf (command, "sh -c 'sleep 1; kill -%d %d' &", SIGINT, pid);
|
|---|
| 241 | if (!(system (command) == 0))
|
|---|
| 242 | return 2;
|
|---|
| 243 | sleep (2);
|
|---|
| 244 | if (!(sigint_occurred == 0))
|
|---|
| 245 | return 3;
|
|---|
| 246 | if (!(pthread_sigmask (SIG_UNBLOCK, &set, NULL) == 0))
|
|---|
| 247 | return 4;
|
|---|
| 248 | if (!(sigint_occurred == 1)) /* This fails on IRIX. */
|
|---|
| 249 | return 5;
|
|---|
| 250 | return 0;
|
|---|
| 251 | }]])],
|
|---|
| 252 | [:],
|
|---|
| 253 | [gl_cv_func_pthread_sigmask_unblock_works=no],
|
|---|
| 254 | [:])
|
|---|
| 255 | m4_ifdef([gl_][THREADLIB], [LIBS=$gl_save_LIBS])
|
|---|
| 256 | ])
|
|---|
| 257 | case "$gl_cv_func_pthread_sigmask_unblock_works" in
|
|---|
| 258 | *no)
|
|---|
| 259 | REPLACE_PTHREAD_SIGMASK=1
|
|---|
| 260 | AC_DEFINE([PTHREAD_SIGMASK_UNBLOCK_BUG], [1],
|
|---|
| 261 | [Define to 1 if pthread_sigmask() unblocks signals incorrectly.])
|
|---|
| 262 | ;;
|
|---|
| 263 | esac
|
|---|
| 264 | fi
|
|---|
| 265 | ])
|
|---|
| 266 |
|
|---|
| 267 | # Prerequisite of lib/pthread_sigmask.c.
|
|---|
| 268 | AC_DEFUN([gl_PREREQ_PTHREAD_SIGMASK],
|
|---|
| 269 | [
|
|---|
| 270 | if test $HAVE_PTHREAD_SIGMASK = 1; then
|
|---|
| 271 | AC_DEFINE([HAVE_PTHREAD_SIGMASK], [1],
|
|---|
| 272 | [Define to 1 if the pthread_sigmask function can be used (despite bugs).])
|
|---|
| 273 | fi
|
|---|
| 274 | ])
|
|---|