This test is racy. It relies on signals interrupting sleeps to do
synchronization between processes.

Reported failure: https://bugzilla.novell.com/show_bug.cgi?id=375897

Instead use a synchronization pipe to have the child thread send messages to
the parent thread (with reasonable timeouts since this is testing blocking
calls).

# Apply to root of ltp-full-20081031 tree

$ cd testcases/open_posix_testsuite/
$ make conformance/interfaces/mq_send/5-1.test
$ conformance/interfaces/mq_send/5-1.test

Signed-off-by: Brandon Philips <[EMAIL PROTECTED]>

---
 testcases/open_posix_testsuite/conformance/interfaces/mq_send/5-1.c |   53 
+++---
 testcases/open_posix_testsuite/include/posixtest.h                  |   81 
++++++++++
 2 files changed, 106 insertions(+), 28 deletions(-)

Index: 
ltp-full-20081031/testcases/open_posix_testsuite/conformance/interfaces/mq_send/5-1.c
===================================================================
--- 
ltp-full-20081031.orig/testcases/open_posix_testsuite/conformance/interfaces/mq_send/5-1.c
+++ 
ltp-full-20081031/testcases/open_posix_testsuite/conformance/interfaces/mq_send/5-1.c
@@ -42,14 +42,7 @@
 char gqname[NAMESIZE];
 mqd_t gqueue;
 
-/*
- * This handler is just used to catch the signal and stop sleep (so the
- * parent knows the child is still busy sending signals).
- */
-void stopsleep_handler(int signo)
-{
-       return;
-}
+int sync_pipes[2];
 
 int main()
 {
@@ -70,51 +63,55 @@ int main()
                 return PTS_UNRESOLVED;
         }
 
+       if (sync_pipe_create(sync_pipes) == -1) {
+                perror("sync_pipe_create() did not return success");
+                return PTS_UNRESOLVED;
+       }
+
        if ((pid = fork()) == 0) {
                /* child here */
                int i;
 
-               sleep(1);  // give parent time to set up handler
                for (i=0; i<MAXMSG+1; i++) {
                        mq_send(gqueue, msgptr, strlen(msgptr), 1);
-                       /* send signal to parent each time message is sent */
-                       kill(getppid(), SIGABRT);
+                       if (sync_pipe_notify(sync_pipes) < 0) {
+                               perror("sync_pipe_notify() did not return 
success");
+                               return PTS_UNRESOLVED;
+                       }
                }
+
        } else {
                /* parent here */
                struct sigaction act;
-               int j;
+               int j = 0;
+               int r;
 
-               /* parent runs stopsleep_handler when sleep is interrupted
-                   by child */
-               act.sa_handler=stopsleep_handler;
-               act.sa_flags=0;
-               sigemptyset(&act.sa_mask);
-               sigaction(SIGABRT, &act, 0);
-
-               for (j=0; j<MAXMSG+1; j++) {  // "infinite" loop
-                       if (sleep(3) == 0) {
-                       /* If sleep finished, child is probably blocking */
-                               break;
+               /* wait for child to reach MAXMSG */
+               for (j = 0; j < MAXMSG; j++) {
+                       /* set a long timeout since we are expecting success */
+                       if (sync_pipe_wait_select(sync_pipes, 60) != 0) {
+                               printf("sync_pipe_wait\n");
+                               return PTS_FAIL;
                        }
                }
 
-               if (j == MAXMSG+1) {
+               /* if we don't timeout here then we got too many messages, 
child never blocked */
+               if (sync_pipe_wait_select(sync_pipes, 2) != -ETIMEDOUT) {
                        printf("Child never blocked\n");
                        kill(pid, SIGKILL); //kill child
                        return PTS_FAIL;
                }
 
-               /* receive message and allow blocked send to complete */
+               /* receive one message and allow child's mq_send to complete */
                if (mq_receive(gqueue, msgrcd, BUFFER, &pri) == -1) {
                        perror("mq_receive() did not return success");
                        unresolved = 1;
                }
 
-                if (sleep(3) == 0) {
+               /* child has 5 seconds to call mq_send() again and notify us */
+               if (sync_pipe_wait_select(sync_pipes, 5) == -ETIMEDOUT) {
                         /*
-                         * mq_send didn't succeed and interrupt sleep()
-                         * with a signal
+                         * mq_send didn't unblock
                          */
                         kill(pid, SIGKILL); //kill child
                         printf("mq_send() didn't appear to complete\n");
Index: ltp-full-20081031/testcases/open_posix_testsuite/include/posixtest.h
===================================================================
--- ltp-full-20081031.orig/testcases/open_posix_testsuite/include/posixtest.h
+++ ltp-full-20081031/testcases/open_posix_testsuite/include/posixtest.h
@@ -14,3 +14,84 @@
 #define PTS_UNRESOLVED  2
 #define PTS_UNSUPPORTED 4
 #define PTS_UNTESTED    5
+
+#include <sys/select.h>
+
+
+int sync_pipe_create(int fd[])
+{
+        return pipe (fd);
+}
+
+int sync_pipe_close(int fd[])
+{
+        int r = 0;
+
+        if (fd[0] != -1)
+                r = close (fd[0]);
+        if (fd[1] != -1)
+                r |= close (fd[1]);
+        return r;
+}
+
+int sync_pipe_wait(int fd[])
+{
+        char buf;
+        int r;
+
+        if (fd[1] != -1) {
+                close (fd[1]);
+                fd[1] = -1;
+        }
+
+        r = read (fd[0], &buf, 1);
+
+        if ((r != 1) || (buf != 'A'))
+                return -1;
+        return 0;
+}
+
+int sync_pipe_wait_select(int fd[], long tv_sec)
+{
+        char buf;
+        int r;
+       fd_set rfds;
+       struct timeval tv;
+
+       tv.tv_sec = tv_sec;
+       tv.tv_usec = 0;
+
+        if (fd[1] != -1) {
+                close (fd[1]);
+                fd[1] = -1;
+        }
+
+       FD_ZERO(&rfds);
+       FD_SET(fd[0], &rfds);
+
+       r = select(fd[0] + 1, &rfds, NULL, NULL, &tv);
+
+       if (FD_ISSET(fd[0], &rfds)) {
+               return sync_pipe_wait(fd);
+       }
+
+       return -ETIMEDOUT;
+}
+
+
+int sync_pipe_notify(int fd[])
+{
+        char buf = 'A';
+        int r;
+
+        if (fd[0] != -1) {
+                close (fd[0]);
+                fd[0] = -1;
+        }
+
+        r = write (fd[1], &buf, 1);
+
+        if (r != 1)
+                return -1;
+        return 0;
+}

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to