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