Fix a race condition generating stampfiles.
This makes 'redo -j1000' now run successfully in t/curse, except that we foolishly generate the same files more than once. But at least not more than once *in parallel*.
This commit is contained in:
parent
ec6f61949b
commit
a5ff60ccf3
2 changed files with 16 additions and 10 deletions
|
|
@ -1,16 +1,20 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
import sys, os
|
import sys, os, errno
|
||||||
import vars
|
import vars
|
||||||
from helpers import sname, add_dep, debug, err, mkdirp, unlink
|
from helpers import sname, add_dep, debug, err, mkdirp, unlink
|
||||||
|
|
||||||
|
|
||||||
def _dirty_deps(t, depth, fromdir):
|
def _dirty_deps(t, depth, fromdir):
|
||||||
debug('%s?%s\n' % (depth, t))
|
debug('%s?%s\n' % (depth, t))
|
||||||
if not os.path.exists(sname('stamp', t, fromdir)):
|
try:
|
||||||
debug('%s-- DIRTY (no stamp)\n' % depth)
|
stamptime = os.stat(sname('stamp', t, fromdir)).st_mtime
|
||||||
return True
|
except OSError, e:
|
||||||
|
if e.errno == errno.ENOENT:
|
||||||
|
debug('%s-- DIRTY (no stamp)\n' % depth)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
stamptime = os.stat(sname('stamp', t, fromdir)).st_mtime
|
|
||||||
try:
|
try:
|
||||||
realtime = os.stat(os.path.join(fromdir or '', t)).st_mtime
|
realtime = os.stat(os.path.join(fromdir or '', t)).st_mtime
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|
|
||||||
12
redo.py
12
redo.py
|
|
@ -79,17 +79,19 @@ def find_do_file(t):
|
||||||
|
|
||||||
def stamp(t):
|
def stamp(t):
|
||||||
stampfile = sname('stamp', t)
|
stampfile = sname('stamp', t)
|
||||||
|
newstampfile = sname('stamp' + str(os.getpid()), t)
|
||||||
depfile = sname('dep', t)
|
depfile = sname('dep', t)
|
||||||
if not os.path.exists(vars.BASE + '/.redo'):
|
if not os.path.exists(vars.BASE + '/.redo'):
|
||||||
# .redo might not exist in a 'make clean' target
|
# .redo might not exist in a 'make clean' target
|
||||||
return
|
return
|
||||||
open(stampfile, 'w').close()
|
open(newstampfile, 'w').close()
|
||||||
open(depfile, 'a').close()
|
|
||||||
try:
|
try:
|
||||||
mtime = os.stat(t).st_mtime
|
mtime = os.stat(t).st_mtime
|
||||||
except OSError:
|
except OSError:
|
||||||
mtime = 0
|
mtime = 0
|
||||||
os.utime(stampfile, (mtime, mtime))
|
os.utime(newstampfile, (mtime, mtime))
|
||||||
|
os.rename(newstampfile, stampfile)
|
||||||
|
open(depfile, 'a').close()
|
||||||
|
|
||||||
|
|
||||||
def _preexec(t):
|
def _preexec(t):
|
||||||
|
|
@ -106,8 +108,8 @@ def _build(t):
|
||||||
# an existing source file that is not marked as a generated file.
|
# an existing source file that is not marked as a generated file.
|
||||||
# This step is mentioned by djb in his notes. It turns out to be
|
# This step is mentioned by djb in his notes. It turns out to be
|
||||||
# important to prevent infinite recursion. For example, a rule
|
# important to prevent infinite recursion. For example, a rule
|
||||||
# called default.o.do could be used to try to produce hello.c.o,
|
# called default.c.do could be used to try to produce hello.c,
|
||||||
# which is stupid since hello.c is a static file.
|
# which is undesirable since hello.c existed already.
|
||||||
stamp(t)
|
stamp(t)
|
||||||
return # success
|
return # success
|
||||||
unlink(sname('dep', t))
|
unlink(sname('dep', t))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue