This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 1/3] Use reliable sem_wait interruption in nptl/tst-sem6.
- From: Torvald Riegel <triegel at redhat dot com>
- To: GLIBC Devel <libc-alpha at sourceware dot org>
- Date: Fri, 05 Dec 2014 19:52:57 +0100
- Subject: [PATCH 1/3] Use reliable sem_wait interruption in nptl/tst-sem6.
- Authentication-results: sourceware.org; auth=none
- References: <1417804668 dot 22797 dot 108 dot camel at triegel dot csb>
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;
}