Now both child and parent can wait for each other which was not
possible using only one named pipe as it would cause race condition.

Example of race condition which can be resolved by using
two checkpoints instead of one (following is parent code):
TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint);

/* child now doing some action on which parent must wait to finish */
TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint);

The problem here is that PARENT_WAIT() is usually executed
immediately after SIGNAL_CHILD() which causes:
1) "Wrong data read from the pipe at ..." error message
2) that inside child, the call of CHILD_WAIT() hangs, because read
   was done from parent (by PARENT_WAIT() call)

Signed-off-by: Matus Marhefka <mmarh...@redhat.com>
---
 include/tst_checkpoint.h |  4 +++-
 lib/tst_checkpoint.c     | 37 +++++++++++++++++++++++--------------
 2 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/include/tst_checkpoint.h b/include/tst_checkpoint.h
index f2d7efe..a9602d0 100644
--- a/include/tst_checkpoint.h
+++ b/include/tst_checkpoint.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 Cyril Hrubis chru...@suse.cz
+ * Copyright (C) 2014 Matus Marhefka mmarh...@redhat.com
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -36,9 +37,10 @@
 
 #include "test.h"
 
-#define TST_CHECKPOINT_FIFO "tst_checkpoint_fifo"
 
+#define FIFO_LEN 30
 struct tst_checkpoint {
+       char file[FIFO_LEN];
        /* child return value in case of failure */
        int retval;
        /* timeout in msecs */
diff --git a/lib/tst_checkpoint.c b/lib/tst_checkpoint.c
index 695cd3e..77e1b91 100644
--- a/lib/tst_checkpoint.c
+++ b/lib/tst_checkpoint.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 Cyril Hrubis chru...@suse.cz
+ * Copyright (C) 2014 Matus Marhefka mmarh...@redhat.com
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -70,6 +71,9 @@ int open_wronly_timed(const char *path, unsigned int timeout)
 void tst_checkpoint_init(const char *file, const int lineno,
                          struct tst_checkpoint *self)
 {
+       static unsigned int fifo_counter = 0;
+       int rval;
+
        if (!tst_tmpdir_created()) {
                tst_brkm(TBROK, NULL, "Checkpoint could be used only in test "
                                      "temporary directory at %s:%d",
@@ -77,15 +81,20 @@ void tst_checkpoint_init(const char *file, const int lineno,
        }
        
        /* default values */
+       rval = snprintf(self->file, FIFO_LEN, "tst_checkopoint_fifo_%u",
+                       fifo_counter++);
+       if (rval < 0) {
+               tst_brkm(TBROK, NULL,
+                        "Failed to create a unique temp file name at %s:%d",
+                        file, lineno);
+       }
        self->retval = 1;
        self->timeout = 5000;
 
-       unlink(TST_CHECKPOINT_FIFO);
-
-       if (mkfifo(TST_CHECKPOINT_FIFO, 0666)) {
+       if (mkfifo(self->file, 0666)) {
                tst_brkm(TBROK | TERRNO, NULL,
                         "Failed to create fifo '%s' at %s:%d",
-                        TST_CHECKPOINT_FIFO, file, lineno);
+                        self->file, file, lineno);
        }
 }
 
@@ -97,12 +106,12 @@ void tst_checkpoint_parent_wait(const char *file, const 
int lineno,
        char ch;
        struct pollfd fd;
 
-       fd.fd = open(TST_CHECKPOINT_FIFO, O_RDONLY | O_NONBLOCK);
+       fd.fd = open(self->file, O_RDONLY | O_NONBLOCK);
 
        if (fd.fd < 0) {
                tst_brkm(TBROK | TERRNO, cleanup_fn,
                         "Failed to open fifo '%s' at %s:%d",
-                        TST_CHECKPOINT_FIFO, file, lineno);
+                        self->file, file, lineno);
        }
 
        fd.events = POLLIN;
@@ -121,7 +130,7 @@ void tst_checkpoint_parent_wait(const char *file, const int 
lineno,
        default:
                tst_brkm(TBROK | TERRNO, cleanup_fn,
                         "Poll failed for fifo '%s' at %s:%d",
-                        TST_CHECKPOINT_FIFO, file, lineno);
+                        self->file, file, lineno);
        }
 
        ret = read(fd.fd, &ch, 1);
@@ -157,11 +166,11 @@ void tst_checkpoint_child_wait(const char *file, const 
int lineno,
        int ret, fd;
        char ch;
 
-       fd = open(TST_CHECKPOINT_FIFO, O_RDONLY);
+       fd = open(self->file, O_RDONLY);
 
        if (fd < 0) {
                fprintf(stderr, "CHILD: Failed to open fifo '%s': %s at "
-                       "%s:%d\n", TST_CHECKPOINT_FIFO, strerror(errno),
+                       "%s:%d\n", self->file, strerror(errno),
                        file, lineno);
                exit(self->retval);
        }
@@ -170,7 +179,7 @@ void tst_checkpoint_child_wait(const char *file, const int 
lineno,
 
        if (ret == -1) {
                fprintf(stderr, "CHILD: Failed to read from fifo '%s': %s "
-                       "at %s:%d\n", TST_CHECKPOINT_FIFO, strerror(errno),
+                       "at %s:%d\n", self->file, strerror(errno),
                        file, lineno);
                goto err;
        }
@@ -193,11 +202,11 @@ void tst_checkpoint_signal_parent(const char *file, const 
int lineno,
 {
        int ret, fd;
        
-       fd = open(TST_CHECKPOINT_FIFO, O_WRONLY);
+       fd = open(self->file, O_WRONLY);
 
        if (fd < 0) {
                fprintf(stderr, "CHILD: Failed to open fifo '%s': %s at %s:%d",
-                       TST_CHECKPOINT_FIFO, strerror(errno), file, lineno);
+                       self->file, strerror(errno), file, lineno);
                exit(self->retval);
        }
 
@@ -229,12 +238,12 @@ void tst_checkpoint_signal_child(const char *file, const 
int lineno,
 {
        int ret, fd;
        
-       fd = open_wronly_timed(TST_CHECKPOINT_FIFO, self->timeout);
+       fd = open_wronly_timed(self->file, self->timeout);
 
        if (fd < 0) {
                tst_brkm(TBROK | TERRNO, cleanup_fn,
                         "Failed to open fifo '%s' at %s:%d",
-                        TST_CHECKPOINT_FIFO, file, lineno);
+                        self->file, file, lineno);
        }
 
        ret = write(fd, "p", 1);
-- 
1.8.3.1


------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to