This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/3] Use reliable sem_wait interruption in nptl/tst-sem6.


This makes the nptl/tst-sem6 interrupt sem_wait reliably by letting the
signal handler call sem_post.  This ensures that if the signal handler
should happen to run before sem_wait actually starts, sem_wait will find
an available token and return.  This is necessary if a program does not
want to rely on timing nor on forward progress / fairness guarantees of
the OS scheduler.

It's needed so that Patch 3/3 can do the right thing in face of a
FUTEX_WAIT that may return EINTR on either signal interruption or
spuriously.
commit a819010e2a625eafc66fb1bf1301fcba5c05e5e6
Author: Torvald Riegel <triegel@redhat.com>
Date:   Thu Dec 4 20:43:22 2014 +0100

    Use reliable sem_wait signal interruption in tst-sem6

diff --git a/nptl/tst-sem6.c b/nptl/tst-sem6.c
index 2d9f1ab..3efd4eb 100644
--- a/nptl/tst-sem6.c
+++ b/nptl/tst-sem6.c
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
+sem_t s;
 
 static void
 handler (int sig)
@@ -34,6 +35,10 @@ handler (int sig)
 
   sigaction (SIGALRM, &sa, NULL);
 
+  /* Correctly interrupting a sem_wait without relying on timing assumptions
+     requires using sem_post in the handler.  */
+  sem_post (&s);
+
   /* Rearm the timer.  */
   alarm (1);
 }
@@ -42,7 +47,6 @@ handler (int sig)
 static int
 do_test (void)
 {
-  sem_t s;
   struct sigaction sa;
 
   sa.sa_handler = handler;
@@ -61,14 +65,12 @@ do_test (void)
   alarm (1);
 
   int res = sem_wait (&s);
-  if (res == 0)
-    {
-      puts ("wait succeeded");
-      return 1;
-    }
-  if (res != -1 || errno != EINTR)
+  /* We accept all allowed behavior: Implementations that return EINTR and
+     those that rely on correct interruption through signals to use sem_post
+     in the signal handler.  */
+  if (res != 0 && !(res == -1 && errno == EINTR))
     {
-      puts ("wait didn't fail with EINTR");
+      puts ("wait neiter succeeded nor failed with EINTR");
       return 1;
     }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]