Mail Archives: cygwin/2009/07/22/12:19:13
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
- Raw text -