pthread_sigmask.m4 8.4 KB

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