[CRIU] [PATCH] zdtm: fix race in test_waitsig for multithreaded tests
Andrey Vagin
avagin at openvz.org
Tue Mar 5 09:15:42 EST 2013
A signal can be handled by non-leader thread and sigsuspend
will not be woken up.
kill can send signals to a specified thread, so a futex is used for
synchronization.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
test/zdtm/lib/Makefile | 1 +
test/zdtm/lib/lock.h | 1 +
test/zdtm/lib/ns.c | 6 +++---
test/zdtm/lib/ns.h | 4 +++-
test/zdtm/lib/test.c | 24 +++++++-----------------
5 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/test/zdtm/lib/Makefile b/test/zdtm/lib/Makefile
index c90fcc4..49ef72b 100644
--- a/test/zdtm/lib/Makefile
+++ b/test/zdtm/lib/Makefile
@@ -2,6 +2,7 @@ include ../Makefile.inc
CFLAGS = -g -O2 -Wall -Werror -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
+LIBDIR = .
LIB = libzdtmtst.a
LIBSRC = datagen.c msg.c parseargs.c test.c streamutil.c lock.c ns.c tcp.c
diff --git a/test/zdtm/lib/lock.h b/test/zdtm/lib/lock.h
index 9abd01a..00d6458 100644
--- a/test/zdtm/lib/lock.h
+++ b/test/zdtm/lib/lock.h
@@ -1,6 +1,7 @@
#ifndef CR_LOCK_H_
#define CR_LOCK_H_
+#include <stdint.h>
#include <linux/futex.h>
#include <linux/unistd.h>
#include <sys/time.h>
diff --git a/test/zdtm/lib/ns.c b/test/zdtm/lib/ns.c
index a90b0a0..4b68bde 100644
--- a/test/zdtm/lib/ns.c
+++ b/test/zdtm/lib/ns.c
@@ -103,7 +103,7 @@ static void ns_sig_hand(int signo)
char buf[128] = "";
if (signo == SIGTERM) {
- sig_received = signo;
+ futex_set_and_wake(&sig_received, signo);
len = snprintf(buf, sizeof(buf), "Time to stop and check\n");
goto write_out;
}
@@ -114,9 +114,9 @@ static void ns_sig_hand(int signo)
return;
if (pid == -1) {
if (errno == ECHILD) {
- if (sig_received)
+ if (futex_get(&sig_received))
return;
- sig_received = signo;
+ futex_set_and_wake(&sig_received, signo);
len = snprintf(buf, sizeof(buf),
"All test processes exited\n");
} else {
diff --git a/test/zdtm/lib/ns.h b/test/zdtm/lib/ns.h
index c79cb47..23378bc 100644
--- a/test/zdtm/lib/ns.h
+++ b/test/zdtm/lib/ns.h
@@ -1,7 +1,9 @@
#ifndef __ZDTM_NS__
#define __ZDTM_NS__
-extern volatile sig_atomic_t sig_received;
+#include "lock.h"
+
+extern futex_t sig_received;
extern char *pidfile;
extern void ns_create(int argc, char **argv);
diff --git a/test/zdtm/lib/test.c b/test/zdtm/lib/test.c
index 6ba6364..f0d6483 100644
--- a/test/zdtm/lib/test.c
+++ b/test/zdtm/lib/test.c
@@ -15,13 +15,14 @@
#include <string.h>
#include "zdtmtst.h"
+#include "lock.h"
#include "ns.h"
-volatile sig_atomic_t sig_received = 0;
+futex_t sig_received;
static void sig_hand(int signo)
{
- sig_received = signo;
+ futex_set_and_wake(&sig_received, signo);
}
static char *outfile;
@@ -153,7 +154,7 @@ void test_init(int argc, char **argv)
if (pid) { /* parent will exit when the child is ready */
test_waitsig();
- if (sig_received == SIGCHLD) {
+ if (futex_get(&sig_received) == SIGCHLD) {
int ret;
waitpid(pid, &ret, 0);
@@ -290,7 +291,7 @@ void test_init_ns(int argc, char **argv, unsigned long clone_flags,
/* parent will exit when the child is ready */
test_waitsig();
- if (sig_received == SIGCHLD) {
+ if (futex_get(&sig_received) == SIGCHLD) {
int ret;
waitpid(pid, &ret, 0);
@@ -330,21 +331,10 @@ out:
int test_go(void)
{
- return !sig_received;
+ return !futex_get(&sig_received);
}
void test_waitsig(void)
{
- sigset_t mask, oldmask;
-
- /* Set up the mask of signals to temporarily block. */
- sigemptyset(&mask);
- sigaddset(&mask, SIGTERM);
- sigaddset(&mask, SIGCHLD);
-
- /* Wait for a signal to arrive. */
- sigprocmask(SIG_BLOCK, &mask, &oldmask);
- while (!sig_received)
- sigsuspend (&oldmask);
- sigprocmask (SIG_UNBLOCK, &mask, NULL);
+ futex_wait_while(&sig_received, 0);
}
--
1.7.11.7
More information about the CRIU
mailing list