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