Fix a race condition caused by zap_deps().
We can't just delete all the dependencies at the beginning and re-add them: other people might be checking the same dependencies in parallel. Instead, mark them as delete_me up front, and then after the build completes, remove only the delete_me entries.
This commit is contained in:
parent
80fedc84fe
commit
c64b8a3eb1
2 changed files with 14 additions and 9 deletions
|
|
@ -107,7 +107,7 @@ class BuildJob:
|
||||||
sf.set_static()
|
sf.set_static()
|
||||||
sf.save()
|
sf.save()
|
||||||
return self._after2(0)
|
return self._after2(0)
|
||||||
sf.zap_deps()
|
sf.zap_deps1()
|
||||||
(dofile, basename, ext) = _find_do_file(sf)
|
(dofile, basename, ext) = _find_do_file(sf)
|
||||||
if not dofile:
|
if not dofile:
|
||||||
if os.path.exists(t):
|
if os.path.exists(t):
|
||||||
|
|
@ -235,18 +235,18 @@ class BuildJob:
|
||||||
sf.csum = None
|
sf.csum = None
|
||||||
sf.update_stamp()
|
sf.update_stamp()
|
||||||
sf.set_changed()
|
sf.set_changed()
|
||||||
sf.save()
|
|
||||||
else:
|
else:
|
||||||
unlink(self.tmpname1)
|
unlink(self.tmpname1)
|
||||||
unlink(self.tmpname2)
|
unlink(self.tmpname2)
|
||||||
sf = self.sf
|
sf = self.sf
|
||||||
sf.set_failed()
|
sf.set_failed()
|
||||||
|
sf.zap_deps2()
|
||||||
sf.save()
|
sf.save()
|
||||||
f.close()
|
f.close()
|
||||||
if rv != 0:
|
if rv != 0:
|
||||||
err('%s: exit code %d\n' % (_nice(t),rv))
|
err('%s: exit code %d\n' % (_nice(t),rv))
|
||||||
else:
|
else:
|
||||||
if vars.VERBOSE or vars.XTRACE:
|
if vars.VERBOSE or vars.XTRACE or vars.DEBUG:
|
||||||
log('%s (done)\n\n' % _nice(t))
|
log('%s (done)\n\n' % _nice(t))
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
|
|
||||||
15
state.py
15
state.py
|
|
@ -72,6 +72,7 @@ def db():
|
||||||
" (target int, "
|
" (target int, "
|
||||||
" source int, "
|
" source int, "
|
||||||
" mode not null, "
|
" mode not null, "
|
||||||
|
" delete_me int, "
|
||||||
" primary key (target,source))")
|
" primary key (target,source))")
|
||||||
_db.execute("insert into Schema (version) values (?)", [SCHEMA_VER])
|
_db.execute("insert into Schema (version) values (?)", [SCHEMA_VER])
|
||||||
# eat the '0' runid and File id
|
# eat the '0' runid and File id
|
||||||
|
|
@ -253,17 +254,21 @@ class File(object):
|
||||||
assert(mode in ('c', 'm'))
|
assert(mode in ('c', 'm'))
|
||||||
yield mode,File(cols=cols)
|
yield mode,File(cols=cols)
|
||||||
|
|
||||||
def zap_deps(self):
|
def zap_deps1(self):
|
||||||
debug2('zap-deps: %r\n' % self.name)
|
debug2('zap-deps1: %r\n' % self.name)
|
||||||
_write('delete from Deps where target=?', [self.id])
|
_write('update Deps set delete_me=? where target=?', [True, self.id])
|
||||||
|
|
||||||
|
def zap_deps2(self):
|
||||||
|
debug2('zap-deps2: %r\n' % self.name)
|
||||||
|
_write('delete from Deps where target=? and delete_me=1', [self.id])
|
||||||
|
|
||||||
def add_dep(self, mode, dep):
|
def add_dep(self, mode, dep):
|
||||||
src = File(name=dep)
|
src = File(name=dep)
|
||||||
debug2('add-dep: %r < %s %r\n' % (self.name, mode, src.name))
|
debug2('add-dep: %r < %s %r\n' % (self.name, mode, src.name))
|
||||||
assert(self.id != src.id)
|
assert(self.id != src.id)
|
||||||
_write("insert or replace into Deps "
|
_write("insert or replace into Deps "
|
||||||
" (target, mode, source) values (?,?,?)",
|
" (target, mode, source, delete_me) values (?,?,?,?)",
|
||||||
[self.id, mode, src.id])
|
[self.id, mode, src.id, False])
|
||||||
|
|
||||||
def read_stamp(self):
|
def read_stamp(self):
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue