diff --git a/builder.py b/builder.py index 2e3c8c3..9236f5c 100644 --- a/builder.py +++ b/builder.py @@ -77,7 +77,7 @@ class BuildJob: if vars.NO_OOB or dirty == True: self._start_do() else: - self._start_oob(dirty) + self._start_unlocked(dirty) def _start_do(self): assert(self.lock.owned) @@ -142,15 +142,18 @@ class BuildJob: state.commit() jwack.start_job(t, self._do_subproc, self._after) - def _start_oob(self, dirty): + def _start_unlocked(self, dirty): # out-of-band redo of some sub-objects. This happens when we're not - # quite sure if t needs to be built or not (because some children look - # dirty, but might turn out to be clean thanks to checksums). We have - # to call redo-oob to figure it all out. + # quite sure if t needs to be built or not (because some children + # look dirty, but might turn out to be clean thanks to checksums). + # We have to call redo-unlocked to figure it all out. # - # Note: redo-oob will handle all the updating of sf, so we don't have - # to do it here, nor call _after1. - argv = ['redo-oob', self.sf.name] + [d.name for d in dirty] + # Note: redo-unlocked will handle all the updating of sf, so we + # don't have to do it here, nor call _after1. However, we have to + # hold onto the lock because otherwise we would introduce a race + # condition; that's why it's called redo-unlocked, because it doesn't + # grab a lock. + argv = ['redo-unlocked', self.sf.name] + [d.name for d in dirty] log('(%s)\n' % _nice(self.t)) state.commit() def run(): diff --git a/install.do b/install.do index 3be5df6..3703131 100644 --- a/install.do +++ b/install.do @@ -29,8 +29,9 @@ done python -mcompileall $LIBDIR # binaries -for d in redo redo-ifchange redo-ifcreate redo-always redo-stamp redo-oob; do - fix=$(echo $d | sed 's,-,_,g') +for dd in redo*.py; do + d=$(basename $dd .py) + fix=$(echo $d | sed -e 's,-,_,g') cat >install.wrapper <<-EOF #!/usr/bin/python import sys, os; diff --git a/redo-oob b/redo-oob deleted file mode 120000 index 2b3df53..0000000 --- a/redo-oob +++ /dev/null @@ -1 +0,0 @@ -redo-oob.py \ No newline at end of file diff --git a/redo-unlocked b/redo-unlocked new file mode 120000 index 0000000..c7dcd83 --- /dev/null +++ b/redo-unlocked @@ -0,0 +1 @@ +redo-unlocked.py \ No newline at end of file diff --git a/redo-oob.py b/redo-unlocked.py similarity index 57% rename from redo-oob.py rename to redo-unlocked.py index d93d3a5..9c63412 100755 --- a/redo-oob.py +++ b/redo-unlocked.py @@ -15,14 +15,19 @@ for d in deps: me = state.File(name=target) +# Build the known dependencies of our primary target. This *does* require +# grabbing locks. os.environ['REDO_NO_OOB'] = '1' argv = ['redo-ifchange'] + deps rv = os.spawnvp(os.P_WAIT, argv[0], argv) if rv: sys.exit(rv) -# we know our caller already owns the lock on target, so we don't have to -# acquire another one. +# We know our caller already owns the lock on target, so we don't have to +# acquire another one; tell redo-ifchange about that. Also, REDO_NO_OOB +# persists from up above, because we don't want to do OOB now either. +# (Actually it's most important for the primary target, since it's the one +# who initiated the OOB in the first place.) os.environ['REDO_UNLOCKED'] = '1' argv = ['redo-ifchange', target] rv = os.spawnvp(os.P_WAIT, argv[0], argv)