state.py: reduce race condition between Lock.trylock() and unlock().

If 'redo clean' deletes the lockfile after trylock() succeeds but before
unlock(), then unlock() won't be able to open the pipe in order to release
readers, and any waiters might end up waiting forever.

We can't open the fifo for write until there's at least one reader, so let's
open a reader *just* to let us open a writer.  Then we'll leave them open
until the later unlock(), which can just close them both.
This commit is contained in:
Avery Pennarun 2010-11-22 03:21:17 -08:00
commit 2dbd47100d
3 changed files with 40 additions and 36 deletions

View file

@ -1,4 +1,4 @@
import sys, os, errno
import sys, os, errno, fcntl
import vars
@ -69,3 +69,11 @@ def debug2(s):
log_('redo: %s%s' % (vars.DEPTH, s))
def close_on_exec(fd, yes):
fl = fcntl.fcntl(fd, fcntl.F_GETFD)
fl &= ~fcntl.FD_CLOEXEC
if yes:
fl |= fcntl.FD_CLOEXEC
fcntl.fcntl(fd, fcntl.F_SETFD, fl)