public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: David Rothenberger <daveroth@acm.org>
To: cygwin@cygwin.com
Subject: Re: STC for libapr1 failure
Date: Tue, 14 Feb 2012 21:43:00 -0000	[thread overview]
Message-ID: <4F3AD58A.9040106@acm.org> (raw)
In-Reply-To: <20120214182452.GK25918@calimero.vinschen.de>

[-- Attachment #1: Type: text/plain, Size: 1593 bytes --]

On 2/14/2012 10:24 AM, Corinna Vinschen wrote:
> On Feb 14 09:58, David Rothenberger wrote:
>> On 2/14/2012 6:45 AM, Corinna Vinschen wrote:
>>> On Feb 14 15:02, Corinna Vinschen wrote:
>>>> On Feb 14 00:00, David Rothenberger wrote:
>>>>> The libapr1 test cases are failing again for flock locks. This same
>>>>> test case failed with 1.7.9 with a fatal error[1], but that was
>>>>> corrected. The test is no longer encountering the fatal error, but
>>>>> it is producing the wrong result.
>>>>
>>>> Thanks for the testcase.  I think I found the issue.  An event handle
>>>> was closed in the wrong place, outside of the important mutex lock for
>>>> the lock object.  I applied the patch to CVS.  Your testcase now appears
>>>> to run fine for me.  Can you try your entire testsuite again and see
>>>> if there's another failure lurking?
>>>
>>> I uploaded a snapshot for testing.
>>
>> Thanks. The snapshot fixes the flock test case, but now the fcntl test
>> case is failing.
> 
> *Sob*.  How so?  Does it hang or does it allow multiple concurrent
> exclusive locks as the flock case?

Sorry, I should have said. It hangs.

>> I'll try to send an STC for that case, but I suspect the one from last
>> year will have the problem.
> 
> Please send it anyway.

It's attached. If you run it with an argument (any argument), each child
will print its loop count and you can see what happens. If it doesn't
hang for you, try increasing MAX_ITER or CHILDREN at the top.



-- 
David Rothenberger  ----  daveroth@acm.org

QOTD:
        "Oh, no, no...  I'm not beautiful.  Just very, very pretty."

[-- Attachment #2: stc-fcntl-fork.c --]
[-- Type: text/plain, Size: 4653 bytes --]

/***********************************************************************
 * This is a STC to show that fcntl hangs.
 *
 * It tries to use fcntl() for file locking. It creates a temporary
 * file, the uses fork to spawn a number of children. Each child opens
 * the file, then repeatedly uses flock to lock and unlock it.
 *
 * While each child has the lock, it increments a counter stored in
 * shared memory in a racy way, passing the current value to a function
 * which sleeps briefly, then returns the incremented counter.
 *
 * If all works correctly, the counter should end up be incremented
 * by each child iteration.
 *
 * However, this test currently just hangs.
 *
 * Compile: gcc -Wall -o stc-flock-fork stc-flock-fork.c
 ***********************************************************************/

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <sys/mman.h>

#define NUM_TEST_ITERS 1
#define MAX_ITER 10
#define CHILDREN 3
#define MAX_COUNT (MAX_ITER * CHILDREN)

/* Counter stored in shared memory. */
static volatile int *x;

/* A temporary file used for fcntl. */
char tmpfilename[] = "/tmp/fcntlXXXXXX";

struct flock mutex_lock_it;
struct flock mutex_unlock_it;


/* a slower more racy way to implement (*x)++ */
static int increment(int n)
{
    usleep(1);
    return n+1;
}

/* Fork and use fcntl to lock and unlock the file repeatedly in the child. */
void make_child(int childnum, int verbose, int trylock, pid_t *pid)
{
    if ((*pid = fork()) < 0) {
        perror("fork failed");
        exit(1);
    }
    else if (*pid == 0) {
        int fd2 = open(tmpfilename, O_RDWR);
        if (fd2 < 0) {
            perror("child open");
            exit(1);
        }

        int rc;
        int i;
        for (i=0; i<MAX_ITER; ++i) {

            if (verbose)
                printf("Child %d: %d\n", childnum, i);

            /* Get the lock. */
            do {
                rc = fcntl(fd2, F_SETLKW, &mutex_lock_it);
            } while (rc < 0 && errno == EINTR);
            if (rc < 0) {
                perror("lock");
                exit(1);
            }
            
            /* Increment the counter. */
            *x = increment(*x);

            /* Release the lock. */
            do {
                rc = fcntl(fd2, F_SETLKW, &mutex_unlock_it);
            } while (rc < 0 && errno == EINTR);
            if (rc < 0) {
                perror("unlock");
                exit(1);
            }
        }
        exit(0);
    }
}

/* Wait for the child to finish. */
void await_child(pid_t pid)
{
    pid_t pstatus;
    int exit_int;

    do {
        pstatus = waitpid(pid, &exit_int, WUNTRACED);
    } while (pstatus < 0 && errno == EINTR);
}


/* Allocate and attach shared memory */
void init_shm ()
{
    x = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE,
             MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    if (!x) {
        perror ("mmap failed");
        exit (1);
    }
}

int main(int argc, const char * const * argv, const char * const *env)
{
    pid_t child[CHILDREN];
    int n;
    int fd;
    int i;
    int verbose = (argc > 1) ? 1 : 0;
 
    /* Create the temporary file. */
    fd = mkstemp(tmpfilename);
    if (fd < 0) {
        perror("open failed");
        exit(1);
    }
    close(fd);

    /* Initialize shared memory */
    init_shm();

    /* Setup mutexes */
    mutex_lock_it.l_whence = SEEK_SET;   /* from current point */
    mutex_lock_it.l_start = 0;           /* -"- */
    mutex_lock_it.l_len = 0;             /* until end of file */
    mutex_lock_it.l_type = F_WRLCK;      /* set exclusive/write lock */
    mutex_lock_it.l_pid = 0;             /* pid not actually interesting */
    mutex_unlock_it.l_whence = SEEK_SET; /* from current point */
    mutex_unlock_it.l_start = 0;         /* -"- */
    mutex_unlock_it.l_len = 0;           /* until end of file */
    mutex_unlock_it.l_type = F_UNLCK;    /* set exclusive/write lock */
    mutex_unlock_it.l_pid = 0;           /* pid not actually interesting */

    /* Perform the test multiple times. */
    for (i = 0; i < NUM_TEST_ITERS; ++i) {
        /* Create the children. */
        for (n = 0; n < CHILDREN; n++)
            make_child(n, verbose, 0, &child[n]);

        /* Wait for them to finish. */
        for (n = 0; n < CHILDREN; n++)
            await_child(child[n]);

        /* Check counter */
        if (*x != MAX_COUNT) {
            printf("Iteration %d: FAILED: *x (%d) != MAX_COUNT (%d)\n", i, *x, MAX_COUNT);
            exit(1);
        }
    }

    /* Clean up. */
    unlink(tmpfilename);
    return 0;
}


[-- Attachment #3: Type: text/plain, Size: 218 bytes --]

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

  reply	other threads:[~2012-02-14 21:43 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-14  8:00 David Rothenberger
2012-02-14  8:07 ` David Rothenberger
2012-02-14 14:03 ` Corinna Vinschen
2012-02-14 14:46   ` Corinna Vinschen
2012-02-14 17:58     ` David Rothenberger
2012-02-14 18:25       ` Corinna Vinschen
2012-02-14 21:43         ` David Rothenberger [this message]
2012-02-15 15:39           ` Corinna Vinschen
2012-02-15 19:39             ` David Rothenberger
2012-02-15 20:46               ` Corinna Vinschen
2012-02-15 21:16                 ` David Rothenberger
2012-02-15 21:20                   ` Corinna Vinschen
2012-02-15 22:14                     ` David Rothenberger
2012-02-16 14:11                       ` Corinna Vinschen
2012-02-16 15:57                         ` David Rothenberger
2012-02-16 16:06                           ` Corinna Vinschen
2012-02-18 21:52                             ` David Rothenberger
2012-02-20 14:19                               ` Corinna Vinschen
2012-02-20 20:15                                 ` David Rothenberger
2012-02-21  1:29                                 ` Yaakov (Cygwin/X)
2012-02-21  8:59                                   ` Corinna Vinschen
2012-02-21 17:10                                     ` Corinna Vinschen
2012-02-23 14:20                                       ` Corinna Vinschen
2012-02-23 18:43                                         ` Achim Gratz
2012-02-24  3:49                                         ` Yaakov (Cygwin/X)
2012-02-24  8:15                                           ` Corinna Vinschen
  -- strict thread matches above, loose matches on Subject: below --
2011-08-26  0:39 David Rothenberger
2011-08-26 11:16 ` Corinna Vinschen
2011-08-27 20:37   ` Corinna Vinschen
2011-08-27 22:27     ` David Rothenberger
2011-08-29 13:55       ` Corinna Vinschen
2011-08-29 17:09         ` David Rothenberger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F3AD58A.9040106@acm.org \
    --to=daveroth@acm.org \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).