about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nptl/ChangeLog4
-rw-r--r--nptl/tst-cancel4.c266
2 files changed, 266 insertions, 4 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 29aeaf7134..744ac3573c 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,7 @@
+2003-06-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-cancel4.c: Test open, close, pread, pwrite, fsync, and msync.
+
 2003-06-16  Jakub Jelinek  <jakub@redhat.com>
 
 	* sysdeps/pthread/createthread.c (create_thread): Set
diff --git a/nptl/tst-cancel4.c b/nptl/tst-cancel4.c
index 59dc3570dc..fa25c478d7 100644
--- a/nptl/tst-cancel4.c
+++ b/nptl/tst-cancel4.c
@@ -21,6 +21,7 @@
    exit to be called more than once.  */
 
 #include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <pthread.h>
 #include <stddef.h>
@@ -28,6 +29,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/mman.h>
 #include <sys/poll.h>
 #include <sys/select.h>
 #include <sys/socket.h>
@@ -41,10 +43,9 @@
 /* The following interfaces are defined to be cancellation points but
    tests are not yet implemented:
 
-     aio_suspend()         clock_nanosleep()  close()
-     connect()             creat()            fsync()
-     msgrcv()              msgsnd()           msync()
-     open()                pread()            pwrite()
+     aio_suspend()         clock_nanosleep()
+     connect()             creat()
+     msgrcv()              msgsnd()
      sendmsg()             sendto()
      tcdrain()
 
@@ -1296,6 +1297,257 @@ tf_recvmsg (void *arg)
 }
 
 
+static void *
+tf_open (void *arg)
+{
+  if (arg == NULL)
+    // XXX If somebody can provide a portable test case in which open()
+    // blocks we can enable this test to run in both rounds.
+    abort ();
+
+  int r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  open ("Makefile", O_RDONLY);
+
+  pthread_cleanup_pop (0);
+
+  printf ("%s: open returned\n", __FUNCTION__);
+
+  exit (1);
+}
+
+
+static void *
+tf_close (void *arg)
+{
+  if (arg == NULL)
+    // XXX If somebody can provide a portable test case in which close()
+    // blocks we can enable this test to run in both rounds.
+    abort ();
+
+  char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
+  tempfd = mkstemp (fname);
+  if (tempfd == -1)
+    {
+      printf ("%s: mkstemp failed\n", __FUNCTION__);
+      exit (1);
+    }
+  unlink (fname);
+
+  int r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  close (tempfd);
+
+  pthread_cleanup_pop (0);
+
+  printf ("%s: close returned\n", __FUNCTION__);
+
+  exit (1);
+}
+
+
+static void *
+tf_pread (void *arg)
+{
+  if (arg == NULL)
+    // XXX If somebody can provide a portable test case in which pread()
+    // blocks we can enable this test to run in both rounds.
+    abort ();
+
+  tempfd = open ("Makefile", O_RDONLY);
+  if (tempfd == -1)
+    {
+      printf ("%s: cannot open Makefile\n", __FUNCTION__);
+      exit (1);
+    }
+
+  int r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  char mem[10];
+  pread (tempfd, mem, sizeof (mem), 0);
+
+  pthread_cleanup_pop (0);
+
+  printf ("%s: pread returned\n", __FUNCTION__);
+
+  exit (1);
+}
+
+
+static void *
+tf_pwrite (void *arg)
+{
+  if (arg == NULL)
+    // XXX If somebody can provide a portable test case in which pwrite()
+    // blocks we can enable this test to run in both rounds.
+    abort ();
+
+  char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
+  tempfd = mkstemp (fname);
+  if (tempfd == -1)
+    {
+      printf ("%s: mkstemp failed\n", __FUNCTION__);
+      exit (1);
+    }
+  unlink (fname);
+
+  int r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  char mem[10];
+  pwrite (tempfd, mem, sizeof (mem), 0);
+
+  pthread_cleanup_pop (0);
+
+  printf ("%s: pwrite returned\n", __FUNCTION__);
+
+  exit (1);
+}
+
+
+static void *
+tf_fsync (void *arg)
+{
+  if (arg == NULL)
+    // XXX If somebody can provide a portable test case in which fsync()
+    // blocks we can enable this test to run in both rounds.
+    abort ();
+
+  tempfd = open ("Makefile", O_RDONLY);
+  if (tempfd == -1)
+    {
+      printf ("%s: cannot open Makefile\n", __FUNCTION__);
+      exit (1);
+    }
+
+  int r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  fsync (tempfd);
+
+  pthread_cleanup_pop (0);
+
+  printf ("%s: fsync returned\n", __FUNCTION__);
+
+  exit (1);
+}
+
+
+static void *
+tf_msync (void *arg)
+{
+  if (arg == NULL)
+    // XXX If somebody can provide a portable test case in which msync()
+    // blocks we can enable this test to run in both rounds.
+    abort ();
+
+  tempfd = open ("Makefile", O_RDONLY);
+  if (tempfd == -1)
+    {
+      printf ("%s: cannot open Makefile\n", __FUNCTION__);
+      exit (1);
+    }
+  void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
+  if (p == MAP_FAILED)
+    {
+      printf ("%s: mmap failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  int r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  msync (p, 10, 0);
+
+  pthread_cleanup_pop (0);
+
+  printf ("%s: msync returned\n", __FUNCTION__);
+
+  exit (1);
+}
+
+
 static struct
 {
   const char *name;
@@ -1329,6 +1581,12 @@ static struct
   ADD_TEST (recv, 2, 0),
   ADD_TEST (recvfrom, 2, 0),
   ADD_TEST (recvmsg, 2, 0),
+  ADD_TEST (open, 2, 1),
+  ADD_TEST (close, 2, 1),
+  ADD_TEST (pread, 2, 1),
+  ADD_TEST (pwrite, 2, 1),
+  ADD_TEST (fsync, 2, 1),
+  ADD_TEST (msync, 2, 1),
 };
 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))