Replace OK indicator with EC0/EC1.

pull/35/head
David Wilson 8 years ago
parent 82257c2c37
commit 9733668b50

@ -49,9 +49,9 @@ can be recovered by the bootstrapped process later. It then forks into a new
process. process.
After fork, the parent half overwrites its ``stdin`` with the read end of the After fork, the parent half overwrites its ``stdin`` with the read end of the
pipe, and the child half begins reading the :py:mod:`zlib`-compressed payload pipe, and the child half writes the string ``EC0\n``, then begins reading the
supplied on ``stdin`` by the econtext master, and writing the decompressed :py:mod:`zlib`-compressed payload supplied on ``stdin`` by the econtext master,
result to the write-end of the UNIX pipe. and writing the decompressed result to the write-end of the UNIX pipe.
To allow recovery of ``stdin`` for reuse by the bootstrapped process for To allow recovery of ``stdin`` for reuse by the bootstrapped process for
master<->slave communication, it is necessary for the first stage to avoid master<->slave communication, it is necessary for the first stage to avoid
@ -97,14 +97,15 @@ comments, while preserving line numbers. This reduces the compressed payload
by around 20%. by around 20%.
Signalling Success Signalling Success
################## ##################
Once the first stage has decompressed and written the bootstrap source code to Once the first stage has signalled ``EC0\n``, the master knows it is ready to
its parent Python interpreter, it writes the string ``OK\n`` to ``stdout`` receive the compressed bootstrap. After decompressing and writing the bootstrap
before exitting. The master process waits for this string before considering source to its parent Python interpreter, the first stage writes the string
bootstrap successful and the child's ``stdio`` ready to receive messages. ``EC1\n`` to ``stdout`` before exiting. The master process waits for this
string before considering bootstrap successful and the child's ``stdio`` ready
to receive messages.
ExternalContext.main() ExternalContext.main()

@ -68,6 +68,18 @@ def create_child(*args):
return pid, os.dup(parentfp.fileno()) return pid, os.dup(parentfp.fileno())
def discard_until(fd, s):
buf = ''
while not buf.endswith(s):
print 'hi'
s = os.read(fd, 4096)
print ['got', s]
if not s:
raise econtext.core.StreamError('Expected %r, received %r', s, buf)
buf += s
class LogForwarder(object): class LogForwarder(object):
def __init__(self, context): def __init__(self, context):
self._context = context self._context = context
@ -228,8 +240,9 @@ class Stream(econtext.core.Stream):
os.close(W) os.close(W)
os.execv(sys.executable,['econtext:CONTEXT_NAME']) os.execv(sys.executable,['econtext:CONTEXT_NAME'])
else: else:
os.write(1, 'EC0\n')
os.fdopen(W,'wb',0).write(zlib.decompress(sys.stdin.read(input()))) os.fdopen(W,'wb',0).write(zlib.decompress(sys.stdin.read(input())))
print('OK') os.write(1, 'EC1\n')
sys.exit(0) sys.exit(0)
def get_boot_command(self): def get_boot_command(self):
@ -269,10 +282,9 @@ class Stream(econtext.core.Stream):
LOG.debug('%r.connect(): child process stdin/stdout=%r', LOG.debug('%r.connect(): child process stdin/stdout=%r',
self, self.receive_side.fd) self, self.receive_side.fd)
discard_until(self.receive_side.fd, 'EC0\n')
econtext.core.write_all(self.transmit_side.fd, self.get_preamble()) econtext.core.write_all(self.transmit_side.fd, self.get_preamble())
s = os.read(self.receive_side.fd, 4096) discard_until(self.receive_side.fd, 'EC1\n')
if s != 'OK\n':
raise econtext.core.StreamError('Bootstrap failed; stdout: %r', s)
class Broker(econtext.core.Broker): class Broker(econtext.core.Broker):

Loading…
Cancel
Save