Skip to content

Commit c792d7b

Browse files
peffgitster
authored andcommitted
run-command: teach async threads to ignore SIGPIPE
Async processes can be implemented as separate forked processes, or as threads (depending on the NO_PTHREADS setting). In the latter case, if an async thread gets SIGPIPE, it takes down the whole process. This is obviously bad if the main process was not otherwise going to die, but even if we were going to die, it means the main process does not have a chance to report a useful error message. There's also the small matter that forked async processes will not take the main process down on a signal, meaning git will behave differently depending on the NO_PTHREADS setting. This patch fixes it by adding a new flag to "struct async" to block SIGPIPE just in the async thread. In theory, this should always be on (which makes async threads behave more like async processes), but we would first want to make sure that each async process we spawn is careful about checking return codes from write() and would not spew endlessly into a dead pipe. So let's start with it as optional, and we can enable it for specific sites in future patches. The natural name for this option would be "ignore_sigpipe", since that's what it does for the threaded case. But since that name might imply that we are ignoring it in all cases (including the separate-process one), let's call it "isolate_sigpipe". What we are really asking for is isolation. I.e., not to have our main process taken down by signals spawned by the async process. How that is implemented is up to the run-command code. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 739cf49 commit c792d7b

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

run-command.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,16 @@ static void *run_thread(void *data)
588588
struct async *async = data;
589589
intptr_t ret;
590590

591+
if (async->isolate_sigpipe) {
592+
sigset_t mask;
593+
sigemptyset(&mask);
594+
sigaddset(&mask, SIGPIPE);
595+
if (pthread_sigmask(SIG_BLOCK, &mask, NULL) < 0) {
596+
ret = error("unable to block SIGPIPE in async thread");
597+
return (void *)ret;
598+
}
599+
}
600+
591601
pthread_setspecific(async_key, async);
592602
ret = async->proc(async->proc_in, async->proc_out, async->data);
593603
return (void *)ret;

run-command.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct async {
116116
int proc_in;
117117
int proc_out;
118118
#endif
119+
int isolate_sigpipe;
119120
};
120121

121122
int start_async(struct async *async);

0 commit comments

Comments
 (0)