diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-05-18 14:40:06 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-05-18 14:40:06 -0700 |
commit | c555e529ac1d29ed98229698d38f77ebb684a017 (patch) | |
tree | f33f100493be4c07ad3b59d72dbcaeb853d1481b | |
parent | 920f2ea33bdf06dfda272a146c6fbce2ae11bf99 (diff) | |
parent | ed84387a6bfe271e9c1edd277bb6fad54c6a6f0b (diff) | |
download | git-c555e529ac1d29ed98229698d38f77ebb684a017.tar.gz git-c555e529ac1d29ed98229698d38f77ebb684a017.tar.xz |
Merge branch 'jk/push-client-deadlock-fix' into HEAD
Some Windows SDK lacks pthread_sigmask() implementation and fails
to compile the recently updated "git push" codepath that uses it.
* jk/push-client-deadlock-fix:
Windows: only add a no-op pthread_sigmask() when needed
Windows: add pthread_sigmask() that does nothing
t5504: drop sigpipe=ok from push tests
fetch-pack: isolate sigpipe in demuxer thread
send-pack: isolate sigpipe in demuxer thread
run-command: teach async threads to ignore SIGPIPE
send-pack: close demux pipe before finishing async process
-rw-r--r-- | compat/mingw.h | 1 | ||||
-rw-r--r-- | compat/win32/pthread.h | 7 | ||||
-rw-r--r-- | fetch-pack.c | 4 | ||||
-rw-r--r-- | run-command.c | 10 | ||||
-rw-r--r-- | run-command.h | 1 | ||||
-rw-r--r-- | send-pack.c | 7 | ||||
-rwxr-xr-x | t/t5504-fetch-receive-strict.sh | 10 |
7 files changed, 29 insertions, 11 deletions
diff --git a/compat/mingw.h b/compat/mingw.h index 1de70ffd6..edec9e025 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -142,6 +142,7 @@ static inline int fcntl(int fd, int cmd, ...) #define sigemptyset(x) (void)0 static inline int sigaddset(sigset_t *set, int signum) { return 0; } +#define SIG_BLOCK 0 #define SIG_UNBLOCK 0 static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { return 0; } diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h index b6ed9e746..1c164088f 100644 --- a/compat/win32/pthread.h +++ b/compat/win32/pthread.h @@ -104,4 +104,11 @@ static inline void *pthread_getspecific(pthread_key_t key) return TlsGetValue(key); } +#ifndef __MINGW64_VERSION_MAJOR +static inline int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) +{ + return 0; +} +#endif + #endif /* PTHREAD_H */ diff --git a/fetch-pack.c b/fetch-pack.c index f96f6dfb3..b501d5c32 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -15,7 +15,6 @@ #include "version.h" #include "prio-queue.h" #include "sha1-array.h" -#include "sigchain.h" static int transfer_unpack_limit = -1; static int fetch_unpack_limit = -1; @@ -674,10 +673,8 @@ static int sideband_demux(int in, int out, void *data) int *xd = data; int ret; - sigchain_push(SIGPIPE, SIG_IGN); ret = recv_sideband("fetch-pack", xd[0], out); close(out); - sigchain_pop(SIGPIPE); return ret; } @@ -701,6 +698,7 @@ static int get_pack(struct fetch_pack_args *args, demux.proc = sideband_demux; demux.data = xd; demux.out = -1; + demux.isolate_sigpipe = 1; if (start_async(&demux)) die("fetch-pack: unable to fork off sideband" " demultiplexer"); diff --git a/run-command.c b/run-command.c index c72601056..2d6628012 100644 --- a/run-command.c +++ b/run-command.c @@ -590,6 +590,16 @@ static void *run_thread(void *data) struct async *async = data; intptr_t ret; + if (async->isolate_sigpipe) { + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGPIPE); + if (pthread_sigmask(SIG_BLOCK, &mask, NULL) < 0) { + ret = error("unable to block SIGPIPE in async thread"); + return (void *)ret; + } + } + pthread_setspecific(async_key, async); ret = async->proc(async->proc_in, async->proc_out, async->data); return (void *)ret; diff --git a/run-command.h b/run-command.h index 3d1e59e26..49ba764c6 100644 --- a/run-command.h +++ b/run-command.h @@ -116,6 +116,7 @@ struct async { int proc_in; int proc_out; #endif + int isolate_sigpipe; }; int start_async(struct async *async); diff --git a/send-pack.c b/send-pack.c index 047bd18fd..37ee04ea3 100644 --- a/send-pack.c +++ b/send-pack.c @@ -518,6 +518,7 @@ int send_pack(struct send_pack_args *args, demux.proc = sideband_demux; demux.data = fd; demux.out = -1; + demux.isolate_sigpipe = 1; if (start_async(&demux)) die("send-pack: unable to fork off sideband demultiplexer"); in = demux.out; @@ -531,8 +532,10 @@ int send_pack(struct send_pack_args *args, close(out); if (git_connection_is_socket(conn)) shutdown(fd[0], SHUT_WR); - if (use_sideband) + if (use_sideband) { + close(demux.out); finish_async(&demux); + } fd[1] = -1; return -1; } @@ -551,11 +554,11 @@ int send_pack(struct send_pack_args *args, packet_flush(out); if (use_sideband && cmds_sent) { + close(demux.out); if (finish_async(&demux)) { error("error in sideband demultiplexer"); ret = -1; } - close(demux.out); } if (ret < 0) diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index a3e12d295..44f3d5fb2 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -100,11 +100,8 @@ test_expect_success 'push with receive.fsckobjects' ' git config receive.fsckobjects true && git config transfer.fsckobjects false ) && - test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act && - { - test_cmp exp act || - ! test -s act - } + test_must_fail git push --porcelain dst master:refs/heads/test >act && + test_cmp exp act ' test_expect_success 'push with transfer.fsckobjects' ' @@ -114,7 +111,8 @@ test_expect_success 'push with transfer.fsckobjects' ' cd dst && git config transfer.fsckobjects true ) && - test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act + test_must_fail git push --porcelain dst master:refs/heads/test >act && + test_cmp exp act ' cat >bogus-commit <<\EOF |