Subject: Re: [boost] Boost.Process 0.5: Another update/potential candidate for an official library
From: Yakov Galka (ybungalobill_at_[hidden])
Date: 2012-11-14 02:15:27
On Wed, Nov 14, 2012 at 2:24 AM, Boris Schaeling <boris_at_[hidden]> wrote:
> On Tue, 13 Nov 2012 23:42:08 +0100, Yakov Galka <ybungalobill_at_[hidden]>
> [...]Now, consider the following execution order: A1, B1, A2, B2, A3, B3.
>> result is that the write-end of the pipe of b.exe is inherited by a.exe
>> (i.e. 'leaked' into a.exe). b.exe exits, closing its write-end of the
>> However, a.exe still holds (indefinitely) the write-end of b's pipe!
>> Result: thread B will hang until the unrelated process a.exe exits (and
>> perhaps all the children that a.exe created in its own turn).
> On Windows create_pipe() creates non-inheritable handles for the pipe.
> They only become inheritable when an initializer like bind_stdout is used.
> Do you think this solves the problem you outlined?
No, this is *not* enough. There is a race condition between
SetHandleInformation and CreateProcess. That is, the code is essentially
SetHandleInformation(h, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
if during (1) you call to CreateProcess from another thread (with
inheritHandles set to true) then h is leaked to that other process.
> On POSIX one could use initializers like close_fds or close_fds_if to
> explicitly close file descriptors for child processes. Then no "leak"
> should be possible either.
> I don't know whether that would be enough to turn Boost.Process into a
> thread-safe library (I didn't think about thread-safety yet). But then your
> example could be worth adding to the FAQ?
To my understanding on POSIX the situation is even worse, because by
default you inherit *all* descriptors, except those that you explicitly
mark to be closed. The API you need is basically the opposite: inherit none
except those you really want.