pthread_sigmask: Actually use results of gl_THREADLIB.
[gnulib.git] / m4 / pthread_sigmask.m4
1 # pthread_sigmask.m4 serial 12
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
7 AC_DEFUN([gl_FUNC_PTHREAD_SIGMASK],
8 [
9   AC_CHECK_FUNCS_ONCE([pthread_sigmask])
10   LIB_PTHREAD_SIGMASK=
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/.
16   m4_ifdef([gl_][THREADLIB], [
17     AC_REQUIRE([gl_][THREADLIB])
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
62         HAVE_PTHREAD_SIGMASK=0
63       fi
64     fi
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
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".
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
247 ])