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.
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
supplied on ``stdin`` by the econtext master, and writing the decompressed
result to the write-end of the UNIX pipe.
pipe, and the child half writes the string ``EC0\n``, then begins reading the
:py:mod:`zlib`-compressed payload supplied on ``stdin`` by the econtext master,
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
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%.
Signalling Success
##################
Once the first stage has decompressed and written the bootstrap source code to
its parent Python interpreter, it writes the string ``OK\n`` to ``stdout``
before exitting. The master process waits for this string before considering
bootstrap successful and the child's ``stdio`` ready to receive messages.
Once the first stage has signalled ``EC0\n``, the master knows it is ready to
receive the compressed bootstrap. After decompressing and writing the bootstrap
source to its parent Python interpreter, the first stage writes the string
``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()

@ -68,6 +68,18 @@ def create_child(*args):
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):
def __init__(self, context):
self._context = context
@ -228,8 +240,9 @@ class Stream(econtext.core.Stream):
os.close(W)
os.execv(sys.executable,['econtext:CONTEXT_NAME'])
else:
os.write(1, 'EC0\n')
os.fdopen(W,'wb',0).write(zlib.decompress(sys.stdin.read(input())))
print('OK')
os.write(1, 'EC1\n')
sys.exit(0)
def get_boot_command(self):
@ -269,10 +282,9 @@ class Stream(econtext.core.Stream):
LOG.debug('%r.connect(): child process stdin/stdout=%r',
self, self.receive_side.fd)
discard_until(self.receive_side.fd, 'EC0\n')
econtext.core.write_all(self.transmit_side.fd, self.get_preamble())
s = os.read(self.receive_side.fd, 4096)
if s != 'OK\n':
raise econtext.core.StreamError('Bootstrap failed; stdout: %r', s)
discard_until(self.receive_side.fd, 'EC1\n')
class Broker(econtext.core.Broker):

Loading…
Cancel
Save