Hi Brandon,

On Mon, 2008-12-08 at 21:05 -0800, Brandon Philips wrote:
> Version 2: The test failed a few hours after I sent this off. I think it
> was caused by a pid collision which caused the test to use the same
> queue as an earlier failed test that didn't close out its queue. This
> version of the test uses O_EXCL to avoid this. And it cleans up the
> queue on every failure case.
> 
> This test was racy. It relied on signals interrupting sleeps to do
> syncronization between processes. It also didn't cleanup the queue on
> the failure cases and assumed that its queue didn't already exist. This
> patch fixes these issues.
> 
> Reported failures: https://bugzilla.novell.com/show_bug.cgi?id=375897
> 
> Instead use a syncronization 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]>

Thanks for the Patch. Can you please resend it across the present LTP
CVS snapshot, or even the latest Nov 2008 release will do. I find the
following problems in applying the same:

$ patch --dry-run -p1 < mq_send-5-1.c.patch
patching file
testcases/open_posix_testsuite/conformance/interfaces/mq_send/5-1.c
patching file testcases/open_posix_testsuite/include/posixtest.h
Hunk #1 FAILED at 14.
1 out of 1 hunk FAILED -- saving rejects to file
testcases/open_posix_testsuite/include/posixtest.h.rej

Regards--
Subrata

> 
> ---
>  testcases/open_posix_testsuite/conformance/interfaces/mq_send/5-1.c |   84 
> +++++-----
>  testcases/open_posix_testsuite/include/posixtest.h                  |   83 
> +++++++++
>  2 files changed, 130 insertions(+), 37 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
> @@ -1,6 +1,10 @@
>  /*
>   * Copyright (c) 2002, Intel Corporation. All rights reserved.
> + * Copyright (c) 2008, Novell Inc. All rights reserved.
> + *
>   * Created by:  julie.n.fleischer REMOVE-THIS AT intel DOT com
> + * Major fixes by: Brandon Philips <[EMAIL PROTECTED]>
> + *
>   * This file is licensed under the GPL license.  For the full content
>   * of this license, see the COPYING file at the top level of this
>   * source tree.
> @@ -42,13 +46,19 @@
>  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)
> +int sync_pipes[2];
> +
> +int cleanup_for_exit(int gqueue, char *gqname, int ret)
>  {
> -     return;
> +     mq_close(gqueue);
> +     mq_unlink(gqname);
> +
> +     if (ret == PTS_PASS)
> +             printf("Test PASSED\n");
> +     else if (ret == PTS_FAIL)
> +             printf("Test FAILED\n");
> +
> +     return ret;
>  }
> 
>  int main()
> @@ -64,70 +74,70 @@ int main()
> 
>       attr.mq_msgsize = BUFFER;
>       attr.mq_maxmsg = MAXMSG;
> -        gqueue = mq_open(gqname, O_CREAT |O_RDWR, S_IRUSR | S_IWUSR, &attr);
> +
> +     /* Use O_CREAT + O_EXCL to avoid using a previously created queue */
> +        gqueue = mq_open(gqname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | 
> S_IWUSR, &attr);
>          if (gqueue == (mqd_t)-1) {
> -                perror("mq_open() did not return success");
> +             perror("mq_open() did not return success");
>                  return PTS_UNRESOLVED;
>          }
> 
> +     if (sync_pipe_create(sync_pipes) == -1) {
> +             perror("sync_pipe_create() did not return success");
> +             return cleanup_for_exit(gqueue, gqname, 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);
> +                     mq_send(gqueue, msgptr, strlen(msgptr), 1);
> +
> +                     if (sync_pipe_notify(sync_pipes) < 0) {
> +                             perror("sync_pipe_notify() did not return 
> success");
> +                             return cleanup_for_exit(gqueue, gqname, 
> PTS_UNRESOLVED);
> +                     }
>               }
>       } else {
>               /* parent here */
>               struct sigaction act;
>               int j;
> +             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 cleanup_for_exit(gqueue, gqname, 
> 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, 1) != -ETIMEDOUT) {
>                       printf("Child never blocked\n");
>                       kill(pid, SIGKILL); //kill child
> -                     return PTS_FAIL;
> +                     return cleanup_for_exit(gqueue, gqname, 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");
> -                     mq_close(gqueue);
> -                     mq_unlink(gqname);
> -                        printf("Test FAILED\n");
> -                        return PTS_FAIL;
> +                     return cleanup_for_exit(gqueue, gqname, PTS_FAIL);
>                  }
> 
> -             mq_close(gqueue);
> -             mq_unlink(gqname);
> -             printf("Test PASSED\n");
> -             return PTS_PASS;
> +             return cleanup_for_exit(gqueue, gqname, PTS_PASS);
>       }
> 
>       return PTS_UNRESOLVED;
> 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,86 @@
>  #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;
> +     int err;
> +
> +     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);
> +     err = errno;
> +
> +     if (FD_ISSET(fd[0], &rfds)) {
> +             return sync_pipe_wait(fd);
> +     }
> +
> +     return r ? err : -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;
> +}


------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to