delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2011/08/27/18:28:01

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,TW_FC
X-Spam-Check-By: sourceware.org
Message-ID: <4E596F50.3050205@acm.org>
Date: Sat, 27 Aug 2011 15:27:28 -0700
From: David Rothenberger <daveroth AT acm DOT org>
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20110812 Thunderbird/6.0
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: STC for libapr1 failure
References: <4E56EB24 DOT 5000505 AT acm DOT org> <20110826111509 DOT GH10490 AT calimero DOT vinschen DOT de> <20110827203706 DOT GA15411 AT calimero DOT vinschen DOT de>
In-Reply-To: <20110827203706.GA15411@calimero.vinschen.de>
X-IsSubscribed: yes
Reply-To: cygwin AT cygwin DOT com
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

--------------090606020903050607050304
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

On 8/27/2011 1:37 PM, Corinna Vinschen wrote:
> On Aug 26 13:15, Corinna Vinschen wrote:
>> On Aug 25 17:39, David Rothenberger wrote:
>>> For a while now, the test cases that come with libapr1 have been
>>> bombing with this message:
>>>
>>>   *** fatal error - NtCreateEvent(lock): 0xC0000035
>>>
>>> I finally took some time to investigate and have extracted a STC
>>> that demonstrates the problem.
>>
>> Thanks a lot for the testcase.  In theory, the NtCreateEvent call should
>> not have happened at all, since it's called under lock, and the code
>> around that should have made sure that the object doesn't exist at the
>> time.
>>
>> After a few hours of extrem puzzlement, I now finally know what happens.
>> It's kinda hard to explain.
>>
[... very good description of flock problem ...]
> 
> Please test the latest snapshot.  It should fix this problem, as well as
> a starvation problem with signals (and, fwiw, thread cancel events) in
> flock, lockf, and POSIX fcntl locks.

The new snapshot runs the flock STC. Thanks!

I've been building libapr1 without F_SETLK support for a while since
it was also triggering the "NtCreateEvent(lock): 0xC0000035"
error. Since you mentioned fcntl, I tried re-enabling the fcntl
mutexes. They still trigger the error.

I've attached a similar STC that uses fcntl instead of flock.

-- 
David Rothenberger  ----  daveroth AT acm DOT org

"It's what you learn after you know it all that counts."
                -- John Wooden

--------------090606020903050607050304
Content-Type: text/plain;
 name="stc-fcntl-fork.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="stc-fcntl-fork.c"

/***********************************************************************
 * This is a STC that causes the following error on my test machine:
 *   NtCreateEvent(lock): 0xC0000035
 *
 * 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 fcntl to lock and unlock it.
 *
 * This test was extracted from the APR test suite.
 *
 * Compile: gcc -Wall -o stc-fcntl-fork stc-fcntl-fork.c
 ***********************************************************************/

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

#define MAX_ITER 2000
#define CHILDREN 6

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

struct flock mutex_lock_it;
struct flock mutex_unlock_it;

/* Fork and use fcntl to lock and unlock the file repeatedly in the child. */
void make_child(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) {
            do {
                rc = fcntl(fd2, F_SETLKW, &mutex_lock_it);
            } while (rc < 0 && errno == EINTR);
            if (rc < 0) {
                perror("lock");
                exit(1);
            }
            
            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);
}

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

    /* 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 */

    /* Create the children. */
    for (n = 0; n < CHILDREN; n++)
        make_child(0, &child[n]);

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

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


--------------090606020903050607050304
Content-Type: text/plain; charset=us-ascii

--
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
--------------090606020903050607050304--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019