Make jwack... mostly... work with GNU make.
But it seems to be pretty unsolvable in the current form; the problem is that when you're nesting one jwack inside the other and the jobserver is GNU make, there's no way to tell the parent jwack not to use up a token. Thus, if you nest too deeply, it just deadlocks. So this approach isn't really going to work the way it is.
This commit is contained in:
parent
f77e4b5c91
commit
7cbf39d52a
1 changed files with 22 additions and 7 deletions
27
jwack.py
27
jwack.py
|
|
@ -15,6 +15,15 @@ j,jobs= maximum jobs to run at once
|
||||||
_fds = None
|
_fds = None
|
||||||
_tokens = {}
|
_tokens = {}
|
||||||
_waitfds = {}
|
_waitfds = {}
|
||||||
|
_fake_token = 0
|
||||||
|
|
||||||
|
|
||||||
|
def _release(n):
|
||||||
|
global _fake_token
|
||||||
|
if _fake_token:
|
||||||
|
_fake_token = 0
|
||||||
|
n -= 1
|
||||||
|
os.write(_fds[1], 't' * n)
|
||||||
|
|
||||||
|
|
||||||
def setup(maxjobs):
|
def setup(maxjobs):
|
||||||
|
|
@ -36,7 +45,7 @@ def setup(maxjobs):
|
||||||
if maxjobs and not _fds:
|
if maxjobs and not _fds:
|
||||||
# need to start a new server
|
# need to start a new server
|
||||||
_fds = os.pipe()
|
_fds = os.pipe()
|
||||||
os.write(_fds[1], 't' * maxjobs)
|
_release(maxjobs)
|
||||||
os.putenv('MAKEFLAGS',
|
os.putenv('MAKEFLAGS',
|
||||||
'%s --jobserver-fds=%d,%d -j' % (os.getenv('MAKEFLAGS'),
|
'%s --jobserver-fds=%d,%d -j' % (os.getenv('MAKEFLAGS'),
|
||||||
_fds[0], _fds[1]))
|
_fds[0], _fds[1]))
|
||||||
|
|
@ -53,7 +62,7 @@ def wait(want_token):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
p = _waitfds[fd]
|
p = _waitfds[fd]
|
||||||
os.write(_fds[1], 't' * _tokens[fd])
|
_release(_tokens[fd])
|
||||||
b = os.read(fd, 1)
|
b = os.read(fd, 1)
|
||||||
#print 'read: %r' % b
|
#print 'read: %r' % b
|
||||||
if b:
|
if b:
|
||||||
|
|
@ -70,8 +79,14 @@ def wait_for_token():
|
||||||
pfd = atoi(os.getenv('JWACK_PARENT_FD', ''))
|
pfd = atoi(os.getenv('JWACK_PARENT_FD', ''))
|
||||||
#print 'pfd is %d' % pfd
|
#print 'pfd is %d' % pfd
|
||||||
if pfd:
|
if pfd:
|
||||||
#print 'wrote to pfd'
|
# tell parent jwack to give back his token
|
||||||
os.write(pfd, 'j') # tell parent to give back his token
|
os.write(pfd, 'j')
|
||||||
|
else:
|
||||||
|
# parent is a "real" GNU make. He'll assume we already have a token,
|
||||||
|
# so manufacture one and don't bother waiting.
|
||||||
|
global _fake_token
|
||||||
|
_fake_token = 1
|
||||||
|
return
|
||||||
while 1:
|
while 1:
|
||||||
print 'waiting for tokens...'
|
print 'waiting for tokens...'
|
||||||
wait(want_token=1)
|
wait(want_token=1)
|
||||||
|
|
@ -87,7 +102,7 @@ def wait_for_token():
|
||||||
raise
|
raise
|
||||||
if b:
|
if b:
|
||||||
break
|
break
|
||||||
print 'got a token.'
|
print 'got a token (%r).' % b
|
||||||
|
|
||||||
|
|
||||||
def wait_all():
|
def wait_all():
|
||||||
|
|
@ -99,7 +114,7 @@ def force_return_tokens():
|
||||||
n = sum(_tokens.values())
|
n = sum(_tokens.values())
|
||||||
print 'returning %d tokens' % n
|
print 'returning %d tokens' % n
|
||||||
if _fds:
|
if _fds:
|
||||||
os.write(_fds[1], 't' * n)
|
_release(n)
|
||||||
for k in _tokens.keys():
|
for k in _tokens.keys():
|
||||||
_tokens[k] = 0
|
_tokens[k] = 0
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue