+ AC_CHECK_FUNCS(pthread_attr_setstacksize)
+
+ dnl ***********************************
+ dnl *** Checks for working __thread ***
+ dnl ***********************************
+ AC_MSG_CHECKING(for working __thread)
+ if test "x$with_nptl" != "xyes"; then
+ AC_MSG_RESULT(disabled)
+ else
+ AC_TRY_RUN([
+ #include <pthread.h>
+
+ __thread int i;
+ static int res1, res2;
+
+ void thread_main (void *arg)
+ {
+ i = arg;
+ sleep (1);
+ if (arg == 1)
+ res1 = (i == arg);
+ else
+ res2 = (i == arg);
+ }
+
+ int main () {
+ pthread_t t1, t2;
+
+ i = 5;
+
+ pthread_create (&t1, NULL, thread_main, 1);
+ pthread_create (&t2, NULL, thread_main, 2);
+
+ pthread_join (t1, NULL);
+ pthread_join (t2, NULL);
+
+ return !(res1 + res2 == 2);
+ }
+ ], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KW_THREAD)
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+ fi
+
+ dnl **************************************
+ dnl *** Checks for working sigaltstack ***
+ dnl **************************************
+ AC_MSG_CHECKING(for working sigaltstack)
+ if test "x$with_sigaltstack" != "xyes"; then
+ AC_MSG_RESULT(disabled)
+ else
+ AC_TRY_RUN([
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <signal.h>
+ #include <pthread.h>
+ #include <sys/wait.h>
+
+ static void
+ sigsegv_signal_handler (int _dummy, siginfo_t *info, void *context)
+ {
+ exit (0);
+ }
+
+ static void *
+ loop (void *ignored)
+ {
+ char *ptr = NULL;
+
+ *ptr = 0;
+ return NULL;
+ }
+
+ static void
+ child ()
+ {
+ struct sigaction sa;
+ struct sigaltstack sas;
+ pthread_t id;
+ pthread_attr_t attr;
+
+ sa.sa_sigaction = sigsegv_signal_handler;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO | SA_STACK;
+ if (sigaction (SIGSEGV, &sa, NULL) == -1) {
+ perror ("lala");
+ return;
+ }
+
+ sas.ss_sp = malloc (SIGSTKSZ);
+ sas.ss_size = SIGSTKSZ;
+ sas.ss_flags = SS_ONSTACK;
+ if (sigaltstack (&sas, NULL) == -1) {
+ perror ("lala");
+ return;
+ }
+
+ pthread_attr_init (&attr);
+ if (pthread_create(&id, &attr, loop, &attr) != 0) {
+ printf ("failed\n");
+ return;
+ }
+
+ sleep (100);
+ }
+
+ int
+ main ()
+ {
+ pid_t son;
+ int status;
+ int i;
+
+ son = fork ();
+ if (son == -1) {
+ return 1;
+ }
+
+ if (son == 0) {
+ child ();
+ return 0;
+ }
+
+ for (i = 0; i < 3; ++i) {
+ sleep (1);
+ waitpid (son, &status, WNOHANG);
+ if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
+ return 0;
+ }
+
+ kill (son, SIGKILL);
+ return 1;
+ }
+
+ ], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_WORKING_SIGALTSTACK)
+ ], [
+ with_sigaltstack=no
+ AC_MSG_RESULT(no)
+ ])
+ fi