Switch state.py to use sqlite3 instead of filesystem-based stamps.
It passes all tests when run serialized, but still gives weird errors (OperationalError: database is locked) when run with -j5. sqlite3 shouldn't be barfing just because the database is locked, since the default timeout is 5 seconds, and it's dying *way* faster than that.
This commit is contained in:
parent
8dad223225
commit
a62bd50d44
6 changed files with 220 additions and 157 deletions
42
builder.py
42
builder.py
|
|
@ -20,10 +20,10 @@ def _find_do_file(t):
|
|||
for dofile,basename,ext in _possible_do_files(t):
|
||||
debug2('%s: %s ?\n' % (t, dofile))
|
||||
if os.path.exists(dofile):
|
||||
state.add_dep(t, 'm', dofile)
|
||||
state.File(name=t).add_dep('m', dofile)
|
||||
return dofile,basename,ext
|
||||
else:
|
||||
state.add_dep(t, 'c', dofile)
|
||||
state.File(name=t).add_dep('c', dofile)
|
||||
return None,None,None
|
||||
|
||||
|
||||
|
|
@ -53,12 +53,13 @@ class BuildJob:
|
|||
def start(self):
|
||||
assert(self.lock.owned)
|
||||
t = self.t
|
||||
f = state.File(name=t)
|
||||
tmpname = self.tmpname
|
||||
if not self.shouldbuildfunc(t):
|
||||
# target doesn't need to be built; skip the whole task
|
||||
return self._after2(0)
|
||||
if (os.path.exists(t) and not os.path.exists(t + '/.')
|
||||
and not state.is_generated(t)):
|
||||
and not f.is_generated):
|
||||
# an existing source file that was not generated by us.
|
||||
# This step is mentioned by djb in his notes.
|
||||
# For example, a rule called default.c.do could be used to try
|
||||
|
|
@ -67,20 +68,21 @@ class BuildJob:
|
|||
# FIXME: always refuse to redo any file that was modified outside
|
||||
# of redo? That would make it easy for someone to override a
|
||||
# file temporarily, and could be undone by deleting the file.
|
||||
state.unmark_as_generated(t)
|
||||
state.stamp_and_maybe_built(t)
|
||||
debug2("-- static (%r)\n" % t)
|
||||
f.set_static()
|
||||
f.save()
|
||||
return self._after2(0)
|
||||
state.start(t)
|
||||
f.zap_deps()
|
||||
(dofile, basename, ext) = _find_do_file(t)
|
||||
if not dofile:
|
||||
if os.path.exists(t):
|
||||
state.unmark_as_generated(t)
|
||||
state.stamp_and_maybe_built(t)
|
||||
f.is_generated = False
|
||||
f.set_static()
|
||||
f.save()
|
||||
return self._after2(0)
|
||||
else:
|
||||
err('no rule to make %r\n' % t)
|
||||
return self._after2(1)
|
||||
state.stamp_and_maybe_built(dofile)
|
||||
unlink(tmpname)
|
||||
ffd = os.open(tmpname, os.O_CREAT|os.O_RDWR|os.O_EXCL, 0666)
|
||||
close_on_exec(ffd, True)
|
||||
|
|
@ -97,13 +99,19 @@ class BuildJob:
|
|||
if vars.VERBOSE or vars.XTRACE: log_('\n')
|
||||
log('%s\n' % _nice(t))
|
||||
self.argv = argv
|
||||
f.is_generated = True
|
||||
f.save()
|
||||
dof = state.File(name=dofile)
|
||||
dof.set_static()
|
||||
dof.save()
|
||||
jwack.start_job(t, self._do_subproc, self._after)
|
||||
|
||||
def _do_subproc(self):
|
||||
# careful: REDO_PWD was the PWD relative to the STARTPATH at the time
|
||||
# we *started* building the current target; but that target ran
|
||||
# redo-ifchange, and it might have done it from a different directory
|
||||
# than we started it in. So os.getcwd() might be != REDO_PWD right now.
|
||||
# than we started it in. So os.getcwd() might be != REDO_PWD right
|
||||
# now.
|
||||
dn = os.path.dirname(self.t)
|
||||
newp = os.path.realpath(dn)
|
||||
os.environ['REDO_PWD'] = state.relpath(newp, vars.STARTDIR)
|
||||
|
|
@ -153,11 +161,17 @@ class BuildJob:
|
|||
os.rename(tmpname, t)
|
||||
else:
|
||||
unlink(tmpname)
|
||||
state.built(t)
|
||||
state.stamp(t)
|
||||
sf = state.File(name=t)
|
||||
sf.is_generated=True
|
||||
sf.update_stamp()
|
||||
sf.set_changed()
|
||||
sf.save()
|
||||
else:
|
||||
unlink(tmpname)
|
||||
state.unstamp(t)
|
||||
sf = state.File(name=t)
|
||||
sf.stamp = None
|
||||
sf.set_changed()
|
||||
sf.save()
|
||||
f.close()
|
||||
if rv != 0:
|
||||
err('%s: exit code %d\n' % (_nice(t),rv))
|
||||
|
|
@ -226,7 +240,7 @@ def main(targets, shouldbuildfunc):
|
|||
assert(lock.owned)
|
||||
if vars.DEBUG_LOCKS:
|
||||
log('%s (...unlocked!)\n' % _nice(t))
|
||||
if state.stamped(t) == None:
|
||||
if state.File(name=t).stamp == None:
|
||||
err('%s: failed in another thread\n' % _nice(t))
|
||||
retcode[0] = 2
|
||||
lock.unlock()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue