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