Tests for module 'pthread_sigmask'.
authorBruno Haible <bruno@clisp.org>
Fri, 8 Jul 2011 17:12:14 +0000 (19:12 +0200)
committerBruno Haible <bruno@clisp.org>
Fri, 8 Jul 2011 21:27:56 +0000 (23:27 +0200)
* modules/pthread_sigmask-tests: New file.
* tests/test-pthread_sigmask1.c: New file, based on
tests/test-sigprocmask.c.
* tests/test-pthread_sigmask2.c: New file.

ChangeLog
modules/pthread_sigmask-tests [new file with mode: 0644]
tests/test-pthread_sigmask1.c [new file with mode: 0644]
tests/test-pthread_sigmask2.c [new file with mode: 0644]

index e3ea55f9fb1938792f4e7689bc6072514a04349e..465ccafe9819bcbfc2d670ca00ec789b08da4710 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2011-07-08  Bruno Haible  <bruno@clisp.org>
+
+       Tests for module 'pthread_sigmask'.
+       * modules/pthread_sigmask-tests: New file.
+       * tests/test-pthread_sigmask1.c: New file, based on
+       tests/test-sigprocmask.c.
+       * tests/test-pthread_sigmask2.c: New file.
+
 2011-07-08  Jim Meyering  <meyering@redhat.com>
 
        test-getopt.h: avoid warning about an unused variable
diff --git a/modules/pthread_sigmask-tests b/modules/pthread_sigmask-tests
new file mode 100644 (file)
index 0000000..23fc155
--- /dev/null
@@ -0,0 +1,17 @@
+Files:
+tests/test-pthread_sigmask1.c
+tests/test-pthread_sigmask2.c
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+sleep
+thread
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-pthread_sigmask1 test-pthread_sigmask2
+check_PROGRAMS += test-pthread_sigmask1 test-pthread_sigmask2
+test_pthread_sigmask1_LDADD = $(LDADD) @LIB_PTHREAD_SIGMASK@
+test_pthread_sigmask2_LDADD = $(LDADD) @LIB_PTHREAD_SIGMASK@ @LIBMULTITHREAD@
diff --git a/tests/test-pthread_sigmask1.c b/tests/test-pthread_sigmask1.c
new file mode 100644 (file)
index 0000000..d09c216
--- /dev/null
@@ -0,0 +1,95 @@
+/* Test of pthread_sigmask in a single-threaded program.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2011.  */
+
+#include <config.h>
+
+#include <signal.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (pthread_sigmask, int, (int, const sigset_t *, sigset_t *));
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
+
+static volatile int sigint_occurred;
+
+static void
+sigint_handler (int sig)
+{
+  sigint_occurred++;
+}
+
+int
+main (int argc, char *argv[])
+{
+  sigset_t set;
+  int pid = getpid ();
+  char command[80];
+
+  signal (SIGINT, sigint_handler);
+
+  sigemptyset (&set);
+  sigaddset (&set, SIGINT);
+
+  /* Check error handling.  */
+  ASSERT (pthread_sigmask (1729, &set, NULL) == EINVAL);
+
+  /* Block SIGINT.  */
+  ASSERT (pthread_sigmask (SIG_BLOCK, &set, NULL) == 0);
+
+  /* Request a SIGINT signal from outside.  */
+  sprintf (command, "sh -c 'sleep 1; kill -%d %d' &", SIGINT, pid);
+  system (command);
+
+  /* Wait.  */
+  sleep (2);
+
+  /* The signal should not have arrived yet, because it is blocked.  */
+  ASSERT (sigint_occurred == 0);
+
+  /* Unblock SIGINT.  */
+  ASSERT (pthread_sigmask (SIG_UNBLOCK, &set, NULL) == 0);
+
+  /* The signal should have arrived now, because POSIX says
+       "If there are any pending unblocked signals after the call to
+        pthread_sigmask(), at least one of those signals shall be delivered
+        before the call to pthread_sigmask() returns."  */
+  ASSERT (sigint_occurred == 1);
+
+  return 0;
+}
+
+#else
+
+/* On native Windows, getpid() values and the arguments that are passed to
+   the (Cygwin?) 'kill' program are not necessarily related.  */
+
+int
+main ()
+{
+  fputs ("Skipping test: native Windows platform\n", stderr);
+  return 77;
+}
+
+#endif
diff --git a/tests/test-pthread_sigmask2.c b/tests/test-pthread_sigmask2.c
new file mode 100644 (file)
index 0000000..76e8711
--- /dev/null
@@ -0,0 +1,99 @@
+/* Test of pthread_sigmask in a multi-threaded program.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2011.  */
+
+#include <config.h>
+
+#include <signal.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "glthread/thread.h"
+
+#include "macros.h"
+
+#if USE_POSIX_THREADS
+
+static gl_thread_t main_thread;
+static gl_thread_t killer_thread;
+
+static void *
+killer_thread_func (void *arg)
+{
+  sleep (1);
+  pthread_kill (main_thread, SIGINT);
+  return NULL;
+}
+
+static volatile int sigint_occurred;
+
+static void
+sigint_handler (int sig)
+{
+  sigint_occurred++;
+}
+
+int
+main (int argc, char *argv[])
+{
+  sigset_t set;
+
+  signal (SIGINT, sigint_handler);
+
+  sigemptyset (&set);
+  sigaddset (&set, SIGINT);
+
+  /* Check error handling.  */
+  ASSERT (pthread_sigmask (1729, &set, NULL) == EINVAL);
+
+  /* Block SIGINT.  */
+  ASSERT (pthread_sigmask (SIG_BLOCK, &set, NULL) == 0);
+
+  /* Request a SIGINT signal from another thread.  */
+  main_thread = gl_thread_self ();
+  ASSERT (glthread_create (&killer_thread, killer_thread_func, NULL) == 0);
+
+  /* Wait.  */
+  sleep (2);
+
+  /* The signal should not have arrived yet, because it is blocked.  */
+  ASSERT (sigint_occurred == 0);
+
+  /* Unblock SIGINT.  */
+  ASSERT (pthread_sigmask (SIG_UNBLOCK, &set, NULL) == 0);
+
+  /* The signal should have arrived now, because POSIX says
+       "If there are any pending unblocked signals after the call to
+        pthread_sigmask(), at least one of those signals shall be delivered
+        before the call to pthread_sigmask() returns."  */
+  ASSERT (sigint_occurred == 1);
+
+  return 0;
+}
+
+#else
+
+int
+main ()
+{
+  fputs ("Skipping test: POSIX threads not enabled\n", stderr);
+  return 77;
+}
+
+#endif