Re: [PATCH 2/2] fetch: fetch submodules in parallel
- From
Jeff King <peff@peff.net>
- Date
- Sep 14, 2015, 17:17 UTC
- Message-ID
- <20150914171736.GA1548@sigill.intra.peff.net>
- In-Reply-To
- <CAGZ79kaBvVWT1OPMxUAU9N2oaC5TT5wwWew5jS0k_o5J10sKfA@mail.gmail.com>
On Mon, Sep 14, 2015 at 09:46:58AM -0700, Stefan Beller wrote:
Show 14 quoted lines
> I tried implementing a buffering solution for both stdout and stderr, > but that doesn't really workout well if you consider interleaved output > on the pipes as we cannot accurately replay that later on. To do that > we would need to store the timing information of the channels, at least > the relative order of it like: > > (stdout, First comes text to stdout), > (stderr, interrupted by text in stderr) > (stdout, but stdout doesn't bother, blasting more text) > (stderr, continues to interrupt) > > obtaining the information is inherently racy, as all we can do is > polling/reading from both stdout/err as fast as possible but without > proper synchronization mechanisms we cannot be sure.
I don't think you need exact timing information. This is no different than running the commands themselves, with stdout and stderr writing to a pty that your terminal emulator will then read() from. If the program produces intermingled stdout/stderr that clogs up the terminal, that is its problem.
The only difference is that we're going to save it and later replay it all very quickly. So I think it would be sufficient just to retain the original order.
> I will add documentation explaining why the async output case > will only deal with one channel. I chose stderr as that's already > available and needed in this use case.
I suspect you could just set child->stdout_to_stderr in this case, and then you get your ordering for free. But probably in the general case people would want to run inspection commands that produce a useful stdout.
To handle multiple channels, I think you could just do a linked list of buffers rather than a single strbuf. Like:
struct io_chunk {
int channel;
char *buf;
size_t len;
struct io_chunk *next;
};and just keep appending chunks to the list (and to dump them, just walk the list, writing each to the appropriate channel descriptor).
-Peff