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 | ])
|
---|