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