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