summary refs log tree commit diff
path: root/nptl/tst-cancel17.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-06-24 02:50:16 +0000
committerUlrich Drepper <drepper@redhat.com>2003-06-24 02:50:16 +0000
commit67b78ef91b1441c7f94fe03e1bad161d5912f5ac (patch)
treeae9686b619a6a88901b6ecae921be3a8d1b48e47 /nptl/tst-cancel17.c
parent7b0a32a30505e02f2b138b1695096b0ddb2ab62d (diff)
downloadglibc-67b78ef91b1441c7f94fe03e1bad161d5912f5ac.tar.gz
glibc-67b78ef91b1441c7f94fe03e1bad161d5912f5ac.tar.xz
glibc-67b78ef91b1441c7f94fe03e1bad161d5912f5ac.zip
Update.
	* sysdeps/pthread/aio_misc.h: Mark __aio_requests_mutex,
	__aio_enqueue_request, __aio_find_req, __aio_find_req_fd,
	__aio_free_request, __aio_notify, and __aio_sigqueue as hidden.

	* sysdeps/pthread/aio_suspend.c (aio_suspend): Set errno to the result
	of pthread_cond_wait if there was an error.  Use pthread_cleanup_*
	instead of __lbic_cleanup_region_*.
Diffstat (limited to 'nptl/tst-cancel17.c')
-rw-r--r--nptl/tst-cancel17.c147
1 files changed, 133 insertions, 14 deletions
diff --git a/nptl/tst-cancel17.c b/nptl/tst-cancel17.c
index 65b8c73ef8..861ca5ea69 100644
--- a/nptl/tst-cancel17.c
+++ b/nptl/tst-cancel17.c
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <aio.h>
+#include <errno.h>
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -44,19 +45,44 @@ tf (void *arg)
   int r = pthread_barrier_wait (&b);
   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
     {
-      puts ("barrier_wait failed");
+      puts ("tf: barrier_wait failed");
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  const struct aiocb *l[1] = { arg };
+
+  TEMP_FAILURE_RETRY (aio_suspend (l, 1, NULL));
+
+  pthread_cleanup_pop (0);
+
+  puts ("tf: aio_suspend returned");
+
+  exit (1);
+}
+
+
+static void *
+tf2 (void *arg)
+{
+  int r = pthread_barrier_wait (&b);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("tf2: barrier_wait failed");
       exit (1);
     }
 
   pthread_cleanup_push (cl, NULL);
 
   const struct aiocb *l[1] = { arg };
+  struct timespec ts = { .tv_sec = 1000, .tv_nsec = 0 };
 
-  aio_suspend (l, 1, NULL);
+  TEMP_FAILURE_RETRY (aio_suspend (l, 1, &ts));
 
   pthread_cleanup_pop (0);
 
-  puts ("aio_suspend returned");
+  puts ("tf2: aio_suspend returned");
 
   exit (1);
 }
@@ -108,7 +134,7 @@ do_test (void)
   while (nanosleep (&ts, &ts) != 0)
     continue;
 
-  puts ("going to cancel in-time");
+  puts ("going to cancel tf in-time");
   if (pthread_cancel (th) != 0)
     {
       puts ("1st cancel failed");
@@ -129,12 +155,61 @@ do_test (void)
 
   if (cl_called == 0)
     {
-      puts ("cleanup handler not called");
+      puts ("tf cleanup handler not called");
       return 1;
     }
   if (cl_called > 1)
     {
-      puts ("cleanup handler called more than once");
+      puts ("tf cleanup handler called more than once");
+      return 1;
+    }
+
+  cl_called = 0;
+
+  if (pthread_create (&th, NULL, tf2, &a) != 0)
+    {
+      puts ("2nd create failed");
+      return 1;
+    }
+
+  r = pthread_barrier_wait (&b);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("2nd barrier_wait failed");
+      exit (1);
+    }
+
+  ts.tv_sec = 0;
+  ts.tv_nsec = 100000000;
+  while (nanosleep (&ts, &ts) != 0)
+    continue;
+
+  puts ("going to cancel tf2 in-time");
+  if (pthread_cancel (th) != 0)
+    {
+      puts ("2nd cancel failed");
+      return 1;
+    }
+
+  if (pthread_join (th, &status) != 0)
+    {
+      puts ("2nd join failed");
+      return 1;
+    }
+  if (status != PTHREAD_CANCELED)
+    {
+      puts ("2nd thread not canceled");
+      return 1;
+    }
+
+  if (cl_called == 0)
+    {
+      puts ("tf2 cleanup handler not called");
+      return 1;
+    }
+  if (cl_called > 1)
+    {
+      puts ("tf2 cleanup handler called more than once");
       return 1;
     }
 
@@ -156,43 +231,87 @@ do_test (void)
 
   if (pthread_create (&th, NULL, tf, &a) != 0)
     {
-      puts ("2nd create failed");
+      puts ("3rd create failed");
       return 1;
     }
 
-  puts ("going to cancel early");
+  puts ("going to cancel tf early");
   if (pthread_cancel (th) != 0)
     {
-      puts ("2nd cancel failed");
+      puts ("3rd cancel failed");
       return 1;
     }
 
   r = pthread_barrier_wait (&b);
   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
     {
-      puts ("barrier_wait failed");
+      puts ("3rd barrier_wait failed");
       exit (1);
     }
 
   if (pthread_join (th, &status) != 0)
     {
-      puts ("2nd join failed");
+      puts ("3rd join failed");
       return 1;
     }
   if (status != PTHREAD_CANCELED)
     {
-      puts ("2nd thread not canceled");
+      puts ("3rd thread not canceled");
+      return 1;
+    }
+
+  if (cl_called == 0)
+    {
+      printf ("tf cleanup handler not called\n");
+      return 1;
+    }
+  if (cl_called > 1)
+    {
+      printf ("tf cleanup handler called more than once\n");
+      return 1;
+    }
+
+  cl_called = 0;
+
+  if (pthread_create (&th, NULL, tf2, &a) != 0)
+    {
+      puts ("4th create failed");
+      return 1;
+    }
+
+  puts ("going to cancel tf2 early");
+  if (pthread_cancel (th) != 0)
+    {
+      puts ("4th cancel failed");
+      return 1;
+    }
+
+  r = pthread_barrier_wait (&b);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("4th barrier_wait failed");
+      exit (1);
+    }
+
+  if (pthread_join (th, &status) != 0)
+    {
+      puts ("4th join failed");
+      return 1;
+    }
+  if (status != PTHREAD_CANCELED)
+    {
+      puts ("4th thread not canceled");
       return 1;
     }
 
   if (cl_called == 0)
     {
-      printf ("cleanup handler not called\n");
+      printf ("tf2 cleanup handler not called\n");
       return 1;
     }
   if (cl_called > 1)
     {
-      printf ("cleanup handler called more than once\n");
+      printf ("tf2 cleanup handler called more than once\n");
       return 1;
     }