Re: [PATCH] Use line buffering for standard output
Linus Torvalds <torvalds@linux-foundation.org> writes:
Show 15 quoted lines
> On Sun, 3 Aug 2008, Anders Melchiorsen wrote:
>>
>> By always setting stdout to line buffering, we make the output work
>> identically for all output devices.
>
> Please don't.
>
> This is a huge peformance issue for things like
>
> git log -p > file
>
> where we really want it to be fully buffered.
>
> So please just find the place where we do a fork() without flushing
> pending output...
Sure. The sledgehammer approach was partly to get some advice on the proper solution. I now realize that you have generally been careful about this, and so a single flush should be enough.
Below are two alternative proposals, one local and one global. Both of them fix the problem for me, but maybe you were even thinking about a third place?
For the run-command.c one, I was not sure whether to put it inside or outside the ifdef, and I also was not sure whether to add it for start_command(). Not having other testcases, and not knowing Windows, this is the way it ended up.
Cheers, Anders.
From: Anders Melchiorsen <mail@cup.kalibalik.dk>
Date: Mon, 4 Aug 2008 00:21:49 +0200
Subject: [PATCH] Flush stdout in init-db
Before this change, clone outputs "Initialized empty ..." twice if output is piped.
Signed-off-by: Anders Melchiorsen <mail@cup.kalibalik.dk>
---
builtin-init-db.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
Show changes to 2 files +6 −1
builtin-init-db.c, run-command.c
diff --git a/builtin-init-db.c b/builtin-init-db.c
index baf0d09..954c7e9 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -315,11 +315,13 @@ int init_db(const char *template_dir, unsigned int flags)
git_config_set("receive.denyNonFastforwards", "true");
}
- if (!(flags & INIT_DB_QUIET))
+ if (!(flags & INIT_DB_QUIET)) {
printf("%s%s Git repository in %s/\n",
reinit ? "Reinitialized existing" : "Initialized empty",
shared_repository ? " shared" : "",
get_git_dir());
+ fflush(stdout);
+ }
return 0;
}
From: Anders Melchiorsen <mail@cup.kalibalik.dk>
Date: Mon, 4 Aug 2008 00:35:40 +0200
Subject: [PATCH] Flush standard output in start_async
This prevents double output in case stdout is redirected.
Signed-off-by: Anders Melchiorsen <mail@cup.kalibalik.dk>
---
run-command.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/run-command.c b/run-command.c
index a3b28a6..67be079 100644
--- a/run-command.c
+++ b/run-command.c
@@ -304,6 +304,9 @@ int start_async(struct async *async)
async->out = pipe_out[0];
#ifndef __MINGW32__
+ /* Flush output before fork() to avoid cloning the buffer */
+ fflush(stdout);
+
async->pid = fork();
if (async->pid < 0) {
error("fork (async) failed: %s", strerror(errno));