delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2012/02/26/07:58:30

X-Recipient: archive-cygwin AT delorie DOT com
X-Spam-Check-By: sourceware.org
Date: Sun, 26 Feb 2012 13:57:35 +0100
From: Corinna Vinschen <corinna-cygwin AT cygwin DOT com>
To: cygwin AT cygwin DOT com
Subject: Change in flock(2), testers welcome
Message-ID: <20120226125735.GM7755@calimero.vinschen.de>
Reply-To: cygwin AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
MIME-Version: 1.0
User-Agent: Mutt/1.5.21 (2010-09-15)
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

Hi folks,

Cygwin's flock(2) implementation is far from ideal.  While it seems
to work mostly in 1.7.11 now, it has a wide-open definition leak:

BSD locks created by the flock(2) call are bound to a file descriptor.
Consider this situation:

  - process 1 opens a file and forks process 2

  - process 2 calls flock on the inherited descriptor and forks process 3

  - Since the descriptor is shared between all three processes, the lock
    is basically hold by all three processes.  Any one of them can call
    flock again to unlock the file.

And there's the problem in Cygwin so far.  While a child process
inherits a lock on a file, this is not the case with parent processes.
So, in Cygwin, process 2 and 3 share the lock, but process 1 is entirely
ignorant of the lock.  The most important result is that this usage of
the flock(1) tool (taken from the Linux man page) does not work
correctly in Cygwin:

   (
     flock -n 9 || exit 1
     # ... commands executed under lock ...
   ) 9>/var/lock/mylockfile

This works, because the parent shell of the flock tool inherits the
lock from the flock(1) tool, so the sibling commands of flock also
inherit the lock and the entire process group is holding the lock.

I think I have a solution for this scenario now.  It's still not
perfect, but at least it allows to push a lock to the parent process
as well, so the above, typical usage of flock(1) should work.
What the code does is to duplicate the object handle and inject a
remote thread into the parent so it can do the bookkeeping.  Same
thing reverse when a lock is explicitely unlocked.

Please note that this still doesn't work over more than one process
levels.  Only the immediate parent is notified of the lock.  So
something like this:

  (
    (
      flock -n 9 || exit 1 
    }
    # ... commands executed under lock ...
  ) 9>/var/lock/mylockfile

doesn't work yet.  Also, if the parent process is running under another
user account and you're not an administrator account yourself, it will
fail as well.  I'm still looking for a solution which does not involve
to keep a service like cygserver around...

Anyway, I was mostly interested to find a solution for this typical
usage of flock(1) for now.  For those interested in this stuff, please
give it a try.  You'll find it in the latest snapshot I just uploaded to
http://cygwin.com/snapshots/


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

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

- Raw text -


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