Skip to content

Commit

Permalink
builder.py: now the only exported function is main().
Browse files Browse the repository at this point in the history
We can also avoid forking altogether if should_build() returns false.  This
doesn't seem to result in any noticeable speedup, but it's cleaner at least.
  • Loading branch information
apenwarr committed Nov 22, 2010
1 parent 547dbe5 commit 3209316
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 27 deletions.
45 changes: 32 additions & 13 deletions builder.py
Expand Up @@ -41,7 +41,7 @@ def _nice(t):
return os.path.normpath(os.path.join(vars.PWD, t))


def build(t):
def _build(t):
if (os.path.exists(t) and not state.is_generated(t)
and not os.path.exists('%s.do' % t)):
# an existing source file that is not marked as a generated file.
Expand All @@ -68,12 +68,9 @@ def build(t):
ext, # extension (if any), including leading dot
os.path.basename(tmpname) # randomized output file name
]
if vars.VERBOSE:
argv[1] += 'v'
if vars.XTRACE:
argv[1] += 'x'
if vars.VERBOSE or vars.XTRACE:
log_('\n')
if vars.VERBOSE: argv[1] += 'v'
if vars.XTRACE: argv[1] += 'x'
if vars.VERBOSE or vars.XTRACE: log_('\n')
log('%s\n' % _nice(t))
rv = subprocess.call(argv, preexec_fn=lambda: _preexec(t),
stdout=f.fileno())
Expand All @@ -97,7 +94,28 @@ def build(t):
log('%s (done)\n\n' % _nice(t))


def main(targets, buildfunc):
class BuildJob:
def __init__(self, t, lock, shouldbuildfunc, donefunc):
self.t = t
self.lock = lock
self.shouldbuildfunc = shouldbuildfunc
self.donefunc = donefunc

def start(self):
if not self.shouldbuildfunc(self.t):
# target doesn't need to be built; skip the whole task
self.done(self.t, 0)
return
jwack.start_job(self.t, self.lock, self.build, self.done)

def build(self):
return _build(self.t)

def done(self, name, rv):
return self.donefunc(self.t, rv)


def main(targets, shouldbuildfunc):
retcode = [0] # a list so that it can be reassigned from done()
if vars.SHUFFLE:
random.shuffle(targets)
Expand All @@ -106,7 +124,6 @@ def main(targets, buildfunc):

def done(t, rv):
if rv:
#err('%s: exit code was %r\n' % (t, rv))
retcode[0] = 1

for i in range(len(targets)):
Expand All @@ -128,15 +145,17 @@ def done(t, rv):
log('%s (locked...)\n' % _nice(t))
locked.append(t)
else:
jwack.start_job(t, lock,
lambda: buildfunc(t), lambda t,rv: done(t,rv))
j = BuildJob(t, lock, shouldbuildfunc, done)
j.start()

# Now we've built all the "easy" ones. Go back and just wait on the
# remaining ones one by one. This is technically non-optimal; we could
# use select.select() to wait on more than one at a time. But it should
# be rare enough that it doesn't matter, and the logic is easier this way.
while locked or jwack.running():
jwack.wait_all()
# at this point, we don't have any children holding any tokens, so
# it's okay to block below.
if retcode[0] and not vars.KEEP_GOING:
break
if locked:
Expand All @@ -151,6 +170,6 @@ def done(t, rv):
retcode[0] = 2
lock.unlock()
else:
jwack.start_job(t, lock,
lambda: buildfunc(t), lambda t,rv: done(t,rv))
j = BuildJob(t, lock, shouldbuildfunc, done)
j.start()
return retcode[0]
14 changes: 3 additions & 11 deletions redo-ifchange.py
Expand Up @@ -45,25 +45,17 @@ def should_build(t):
return not state.isbuilt(t) and dirty_deps(t, depth = '')


def maybe_build(t):
if should_build(t):
return builder.build(t)


if not vars.TARGET:
err('redo-ifchange: error: must be run from inside a .do\n')
sys.exit(100)

rv = 202
try:
try:
want_build = []
for t in sys.argv[1:]:
targets = sys.argv[1:]
for t in targets:
state.add_dep(vars.TARGET, 'm', t)
if should_build(t):
want_build.append(t)

rv = builder.main(want_build, maybe_build)
rv = builder.main(targets, should_build)
finally:
jwack.force_return_tokens()
except KeyboardInterrupt:
Expand Down
4 changes: 1 addition & 3 deletions redo.py
Expand Up @@ -67,11 +67,9 @@
err('invalid --jobs value: %r\n' % opt.jobs)
jwack.setup(j)
try:
retcode = builder.main(targets, builder.build)
retcode = builder.main(targets, lambda t: True)
finally:
jwack.force_return_tokens()
#if retcode:
# err('exiting: %d\n' % retcode)
sys.exit(retcode)
except KeyboardInterrupt:
sys.exit(200)

0 comments on commit 3209316

Please sign in to comment.