Hi,

I fixed the remaining FIXME in proactor. There is no more known issue
in my subprocesss_stream branch. New change set:
https://codereview.appspot.com/52320045/#ps80001

In fact, changes of proactor_events.py can be applied in a separated
commit (before adding subprocess.py). It fixes the pause/resume
feature of the protocol. The protocol is now paused if more than 64 KB
"will be written", where 64 KB is the total of the buffer *and* the
size of the current pending write.

I tested pass_fds. It looks to be possible to connect more pipes (read
or write, and different than stdin, stdout, stderr) after the creation
of the process.

Example to connect the write end of a pipe:
---
import asyncio
import os, sys
from asyncio.subprocess import *

code = """
import os, sys
fd = int(sys.argv[1])
data = os.read(fd, 1024)
sys.stdout.buffer.write(data)
"""

loop = asyncio.get_event_loop()

@asyncio.coroutine
def task():
    rfd, wfd = os.pipe()
    args = [sys.executable, '-c', code, str(rfd)]
    proc = yield from create_subprocess_exec(*args, pass_fds={rfd}, stdout=PIPE)

    pipe = open(wfd, 'wb', 0)
    transport, protocol = yield from
loop.connect_write_pipe(asyncio.Protocol, pipe)
    transport.write(b'data')

    stdout, stderr = yield from proc.communicate()
    print("stdout = %r" % stdout.decode())

loop.run_until_complete(task())
---


Example to connect the read end of a pipe:
---
import asyncio
import os, sys
from asyncio.subprocess import *

code = """
import os, sys
fd = int(sys.argv[1])
data = os.write(fd, b'data')
os.close(fd)
"""

loop = asyncio.get_event_loop()

@asyncio.coroutine
def task():
    rfd, wfd = os.pipe()
    args = [sys.executable, '-c', code, str(wfd)]

    pipe = open(rfd, 'rb', 0)
    reader = asyncio.StreamReader(loop=loop)
    protocol = asyncio.StreamReaderProtocol(reader, loop=loop)
    transport, _ = yield from loop.connect_read_pipe(lambda: protocol, pipe)

    proc = yield from create_subprocess_exec(*args, pass_fds={wfd})
    yield from proc.wait()

    os.close(wfd)
    data = yield from reader.read()
    print("read = %r" % data.decode())

loop.run_until_complete(task())
---

If the "os.close(wfd)" line is removed, reader.read() blocks forever.
Is it a bug?


"from asyncio.subprocess import *" is "safe": it imports
create_subprocess_exec/shell functions and PIPE, STDOUT and DEVNULL
constants.

Victor

2014-01-30 Victor Stinner <[email protected]>:
> Ok, here is a patch which is my work-in-progress subprocess_stream branch:
> https://codereview.appspot.com/52320045
>
> Ignore the change on Future.set_exception, I forgot to merge with default.
>
> IMO the check_for_hangup parameter should be dropped in proactor, and
> _ProactorWritePipeTransportCheckForHangup should be merged into
> _ProactorWritePipeTransport.
>
> Still in proactor, there is a FIXME in _maybe_pause_protocol(). IMO
> the right fix is to include bytes of pending overlapped write in
> get_write_buffer_size() result.

Reply via email to