This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: flock still buggy


Corinna Vinschen <corinna-cygwin <at> cygwin.com> writes:

> Thanks, but no.  There's at least this one problem left which I simply
> don't know how to fix.  The situation is thus:
> 
>   fd = open()
>   fork ()
>   --> child
>       flock(fd, LOCK_SH);
>       exit ();
> 
> The problem is that the lock disappears when the child exits, even
> though the parent has still an open descriptor to the file.

Oh, right.  So the problem boils down to: if we created the file table entry 
(via open, pipe, socket...) and obtained the lock, then we can properly 
propogate lock details to all duplicate handles (dup) and child processes 
(fork), even across changes in Windows pid (exec).

But if we inherited the file table entry and obtain the lock, we need some way 
to inform all other clients of that file table entry (parent process and any 
other sibling processes) that their fd now owns a lock.

Does the shared memory of cygheap allow us to push information back to parent 
processes?  In the child, can we distinguish between inherited fds vs. fds that 
created a file table entry?

Just thinking aloud: Maybe, for every parent process that calls fork(), we 
create an Event object for each file table entry created in that parent in the 
same flock-dev-ino namespace, and set up a thread that waits indefinitely on 
that Event.  Meanwhile, in children, if flock() is ever called on an inherited 
fd, then part of creating a lock on the fd is also waking up the Event, so that 
the parent can read the shared memory and learn that a lock was obtained.  That 
way, the parent will have a handle prior to the child exiting, so that the 
child no longer breaks the lock.

On the other hand, that may get expensive, since it means creating a lot of 
Events, even though most fork()s don't end up doing flock on something from the 
parent.

But maybe we don't need a new event - we already have a way to signal arbitrary 
processes - maybe the trick is that if flock() ever obtains the lock on an 
inherited file table entry, then it uses the signal mechanism to wake up the 
parent with a special signal number that tells the parent to check if it needs 
to grab a handle to reflect the lock in the child.

Hmm, if the parent has forked multiple times, then it could be more than one 
process that needs to be signaled that a child grabbed a flock.  That could get 
expensive, trying to track through all existing cygwin processes to make all 
such processes grab a new handle because one of their distant relatives called 
flock on the file table entry (particularly if someone tries to use flock on 
the stdout tty).

It seems like for every file table entry we create, we want a piece of shared 
memory listing the processes interested in that file table entry (the list 
grows on fork, and is updated on exec), so that when any one of the owners of a 
handle to that entry creates an flock, it wakes up all related processes to 
also open a handle to the flock.

But no pressure to get this done by 1.7.1.

-- 
Eric Blake




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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]