c73e7e6ec68781e78c08b9ef0aed541e55afa5d3
[gnulib.git] / m4 / pthread_sigmask.m4
1 # pthread_sigmask.m4 serial 9
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   m4_ifdef([gl_THREADLIB], [
12     AC_REQUIRE([gl_THREADLIB])
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   ] ,[
60     dnl gl_THREADLIB is not in use.  Assume the application wants
61     dnl POSIX semantics.
62     if test $ac_cv_func_pthread_sigmask != yes; then
63       gl_save_LIBS=$LIBS
64       AC_SEARCH_LIBS([pthread_sigmask], [pthread c_r])
65       LIBS=$gl_save_LIBS
66       if test "$ac_cv_search_pthread_sigmask" = no; then
67         HAVE_PTHREAD_SIGMASK=0
68       elif test "$ac_cv_search_pthread_sigmask" != 'none required'; then
69         LIB_PTHREAD_SIGMASK=$ac_cv_search_pthread_sigmask
70       fi
71     fi
72   ])
73   AC_SUBST([LIB_PTHREAD_SIGMASK])
74   dnl We don't need a variable LTLIB_PTHREAD_SIGMASK, because when
75   dnl "$gl_threads_api" = posix, $LTLIBMULTITHREAD and $LIBMULTITHREAD are the
76   dnl same: either both empty or both "-lpthread".
77
78   dnl Now test for some bugs in the system function.
79   if test $HAVE_PTHREAD_SIGMASK = 1; then
80     AC_REQUIRE([AC_PROG_CC])
81     AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
82
83     dnl On FreeBSD 6.4, HP-UX 11.31, Solaris 9, in programs that are not linked
84     dnl with -lpthread, the pthread_sigmask() function always returns 0 and has
85     dnl no effect.
86     if test -z "$LIB_PTHREAD_SIGMASK"; then
87       AC_CACHE_CHECK([whether pthread_sigmask works without -lpthread],
88         [gl_cv_func_pthread_sigmask_in_libc_works],
89         [
90           AC_RUN_IFELSE(
91             [AC_LANG_SOURCE([[
92 #include <pthread.h>
93 #include <signal.h>
94 #include <stddef.h>
95 int main ()
96 {
97   sigset_t set;
98   sigemptyset (&set);
99   return pthread_sigmask (1729, &set, NULL) != 0;
100 }]])],
101             [gl_cv_func_pthread_sigmask_in_libc_works=no],
102             [gl_cv_func_pthread_sigmask_in_libc_works=yes],
103             [
104 changequote(,)dnl
105              case "$host_os" in
106                freebsd* | hpux* | solaris | solaris2.[2-9]*)
107                  gl_cv_func_pthread_sigmask_in_libc_works="guessing no";;
108                *)
109                  gl_cv_func_pthread_sigmask_in_libc_works="guessing yes";;
110              esac
111 changequote([,])dnl
112             ])
113         ])
114       case "$gl_cv_func_pthread_sigmask_in_libc_works" in
115         *no)
116           REPLACE_PTHREAD_SIGMASK=1
117           AC_DEFINE([PTHREAD_SIGMASK_INEFFECTIVE], [1],
118             [Define to 1 if pthread_sigmask() may returns 0 and have no effect.])
119           ;;
120       esac
121     fi
122
123     dnl On Cygwin 1.7.5, the pthread_sigmask() has a wrong return value
124     dnl convention: Upon failure, it returns -1 and sets errno.
125     AC_CACHE_CHECK([whether pthread_sigmask returns error numbers],
126       [gl_cv_func_pthread_sigmask_return_works],
127       [
128         gl_save_LIBS="$LIBS"
129         LIBS="$LIBS $LIB_PTHREAD_SIGMASK"
130         AC_RUN_IFELSE(
131           [AC_LANG_SOURCE([[
132 #include <pthread.h>
133 #include <signal.h>
134 #include <stddef.h>
135 int main ()
136 {
137   sigset_t set;
138   sigemptyset (&set);
139   if (pthread_sigmask (1729, &set, NULL) == -1)
140     return 1;
141   return 0;
142 }]])],
143           [gl_cv_func_pthread_sigmask_return_works=yes],
144           [gl_cv_func_pthread_sigmask_return_works=no],
145           [case "$host_os" in
146              cygwin*)
147                gl_cv_func_pthread_sigmask_return_works="guessing no";;
148              *)
149                gl_cv_func_pthread_sigmask_return_works="guessing yes";;
150            esac
151           ])
152         LIBS="$gl_save_LIBS"
153       ])
154     case "$gl_cv_func_pthread_sigmask_return_works" in
155       *no)
156         REPLACE_PTHREAD_SIGMASK=1
157         AC_DEFINE([PTHREAD_SIGMASK_FAILS_WITH_ERRNO], [1],
158           [Define to 1 if pthread_sigmask(), when it fails, returns -1 and sets errno.])
159         ;;
160     esac
161
162     dnl On IRIX 6.5, in a single-threaded program, pending signals are not
163     dnl immediately delivered when they are unblocked through pthread_sigmask,
164     dnl only a little while later.
165     AC_CACHE_CHECK([whether pthread_sigmask unblocks signals correctly],
166       [gl_cv_func_pthread_sigmask_unblock_works],
167       [
168         case "$host_os" in
169           irix*)
170             gl_cv_func_pthread_sigmask_unblock_works="guessing no";;
171           *)
172             gl_cv_func_pthread_sigmask_unblock_works="guessing yes";;
173         esac
174         dnl Here we link against $LIBMULTITHREAD, not only $LIB_PTHREAD_SIGMASK,
175         dnl otherwise we get a false positive on those platforms where
176         dnl $gl_cv_func_pthread_sigmask_in_libc_works is "no".
177         gl_save_LIBS="$LIBS"
178         LIBS="$LIBS $LIBMULTITHREAD"
179         AC_RUN_IFELSE(
180           [AC_LANG_SOURCE([[
181 #include <pthread.h>
182 #include <signal.h>
183 #include <stdio.h>
184 #include <stdlib.h>
185 #include <unistd.h>
186 static volatile int sigint_occurred;
187 static void
188 sigint_handler (int sig)
189 {
190   sigint_occurred++;
191 }
192 int main ()
193 {
194   sigset_t set;
195   int pid = getpid ();
196   char command[80];
197   signal (SIGINT, sigint_handler);
198   sigemptyset (&set);
199   sigaddset (&set, SIGINT);
200   if (!(pthread_sigmask (SIG_BLOCK, &set, NULL) == 0))
201     return 1;
202   sprintf (command, "sh -c 'sleep 1; kill -%d %d' &", SIGINT, pid);
203   if (!(system (command) == 0))
204     return 2;
205   sleep (2);
206   if (!(sigint_occurred == 0))
207     return 3;
208   if (!(pthread_sigmask (SIG_UNBLOCK, &set, NULL) == 0))
209     return 4;
210   if (!(sigint_occurred == 1)) /* This fails on IRIX.  */
211     return 5;
212   return 0;
213 }]])],
214           [:],
215           [gl_cv_func_pthread_sigmask_unblock_works=no],
216           [:])
217         LIBS="$gl_save_LIBS"
218       ])
219     case "$gl_cv_func_pthread_sigmask_unblock_works" in
220       *no)
221         REPLACE_PTHREAD_SIGMASK=1
222         AC_DEFINE([PTHREAD_SIGMASK_UNBLOCK_BUG], [1],
223           [Define to 1 if pthread_sigmask() unblocks signals incorrectly.])
224         ;;
225     esac
226   fi
227 ])
228
229 # Prerequisite of lib/pthread_sigmask.c.
230 AC_DEFUN([gl_PREREQ_PTHREAD_SIGMASK],
231 [
232   if test $HAVE_PTHREAD_SIGMASK = 1; then
233     AC_DEFINE([HAVE_PTHREAD_SIGMASK], [1],
234       [Define to 1 if the pthread_sigmask function can be used (despite bugs).])
235   fi
236 ])