Am 01.11.2016 um 00:15 schrieb Gavin Lambert:
On 28/10/2016 07:33, Klemens Morgenstern wrote:
6. It is a *very* serious design flaw that i/o deadlocks if you try to read after the child exits. The documentation suggests this is because maybe because we are redirecting to a file. This is not a good reason to have i/o deadlocking seeing as every system I've ever used it is possible to configure the pipes to error if you try to read from a closed pipe. The default should be to always error on a closed pipe read, and if the user is foolish enough to redirect to a file then it's on them to work around it rather than forcing very unhelpful and bug inducing behaviour on every user.
That is not the reason. In order to use boost.asio with pipes, you need to use named pipes on windows, which behave like file-handles. Therefore (afaik) the pipe does not get closed automatically, hence I cannot guarantee that a pipe will be closed automatically. The deadlock is caused for that reason: the pipe is still open, but no one is writing into it.
+1 for deadlock on read from exited process being a non-starter. (The only acceptable deadlock is for obviously silly user code, eg. synchronous blocking on reading the child's stdout without providing sufficient stdin to it. But trying to read stdout after the child has closed is not one of those cases.)
I do agree, but I cannot consistently guarantee that. The only way to ensure that would be something like FD_CLOEXEC, but there's no such thing on windows.
I don't really understand your explanation. File handles do get closed automatically on process exit, so as long as the child process is the only one that has the write-end of the pipe open, then the read-end should be guaranteed to EOF when the child exits on all platforms.
Not if you have a named pipe, that's the problem here. It could of course be that I missed something, but as far as I tested, you won't have a guaranteed close there.
If the pipe handles are being inherited by the child process (as with fork, or explicit in CreateProcess) then you should set parent-only handles to be non-inheritable prior to forking and close child-only handles in the parent immediately after forking.
Well as for the first: I don't know if it's parent-only in the function, since forwarding is possible. For the second: yes I could assume that a pipe will not be reused and close the half, but that wouldn't do anything for the problem at hand as explained above.
Also, you shouldn't have to use named pipes. CreatePipe will create anonymous pipes, which are just handles, and ASIO supports read/write operations on arbitrary handles just fine. For launching child processes this should be strongly preferred over named pipes.
It does not support that, you'll get an exception if you try it. THAT is the main problem. In order to make it asynchronous, you need the overlapped stuff, and you cannot do that with anonymous pipes. That is the main reason this doesn't work, becaues I have to assume that any given pipe may be a named one.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost