Skip to content

Commit c555e52

Browse files
committed
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
2 parents 920f2ea + ed84387 commit c555e52

File tree

7 files changed

+29
-11
lines changed

7 files changed

+29
-11
lines changed

compat/mingw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static inline int fcntl(int fd, int cmd, ...)
142142
#define sigemptyset(x) (void)0
143143
static inline int sigaddset(sigset_t *set, int signum)
144144
{ return 0; }
145+
#define SIG_BLOCK 0
145146
#define SIG_UNBLOCK 0
146147
static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
147148
{ return 0; }

compat/win32/pthread.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,11 @@ static inline void *pthread_getspecific(pthread_key_t key)
104104
return TlsGetValue(key);
105105
}
106106

107+
#ifndef __MINGW64_VERSION_MAJOR
108+
static inline int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
109+
{
110+
return 0;
111+
}
112+
#endif
113+
107114
#endif /* PTHREAD_H */

fetch-pack.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "version.h"
1616
#include "prio-queue.h"
1717
#include "sha1-array.h"
18-
#include "sigchain.h"
1918

2019
static int transfer_unpack_limit = -1;
2120
static int fetch_unpack_limit = -1;
@@ -674,10 +673,8 @@ static int sideband_demux(int in, int out, void *data)
674673
int *xd = data;
675674
int ret;
676675

677-
sigchain_push(SIGPIPE, SIG_IGN);
678676
ret = recv_sideband("fetch-pack", xd[0], out);
679677
close(out);
680-
sigchain_pop(SIGPIPE);
681678
return ret;
682679
}
683680

@@ -701,6 +698,7 @@ static int get_pack(struct fetch_pack_args *args,
701698
demux.proc = sideband_demux;
702699
demux.data = xd;
703700
demux.out = -1;
701+
demux.isolate_sigpipe = 1;
704702
if (start_async(&demux))
705703
die("fetch-pack: unable to fork off sideband"
706704
" demultiplexer");

run-command.c

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

593+
if (async->isolate_sigpipe) {
594+
sigset_t mask;
595+
sigemptyset(&mask);
596+
sigaddset(&mask, SIGPIPE);
597+
if (pthread_sigmask(SIG_BLOCK, &mask, NULL) < 0) {
598+
ret = error("unable to block SIGPIPE in async thread");
599+
return (void *)ret;
600+
}
601+
}
602+
593603
pthread_setspecific(async_key, async);
594604
ret = async->proc(async->proc_in, async->proc_out, async->data);
595605
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);

send-pack.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ int send_pack(struct send_pack_args *args,
518518
demux.proc = sideband_demux;
519519
demux.data = fd;
520520
demux.out = -1;
521+
demux.isolate_sigpipe = 1;
521522
if (start_async(&demux))
522523
die("send-pack: unable to fork off sideband demultiplexer");
523524
in = demux.out;
@@ -531,8 +532,10 @@ int send_pack(struct send_pack_args *args,
531532
close(out);
532533
if (git_connection_is_socket(conn))
533534
shutdown(fd[0], SHUT_WR);
534-
if (use_sideband)
535+
if (use_sideband) {
536+
close(demux.out);
535537
finish_async(&demux);
538+
}
536539
fd[1] = -1;
537540
return -1;
538541
}
@@ -551,11 +554,11 @@ int send_pack(struct send_pack_args *args,
551554
packet_flush(out);
552555

553556
if (use_sideband && cmds_sent) {
557+
close(demux.out);
554558
if (finish_async(&demux)) {
555559
error("error in sideband demultiplexer");
556560
ret = -1;
557561
}
558-
close(demux.out);
559562
}
560563

561564
if (ret < 0)

t/t5504-fetch-receive-strict.sh

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,8 @@ test_expect_success 'push with receive.fsckobjects' '
100100
git config receive.fsckobjects true &&
101101
git config transfer.fsckobjects false
102102
) &&
103-
test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act &&
104-
{
105-
test_cmp exp act ||
106-
! test -s act
107-
}
103+
test_must_fail git push --porcelain dst master:refs/heads/test >act &&
104+
test_cmp exp act
108105
'
109106

110107
test_expect_success 'push with transfer.fsckobjects' '
@@ -114,7 +111,8 @@ test_expect_success 'push with transfer.fsckobjects' '
114111
cd dst &&
115112
git config transfer.fsckobjects true
116113
) &&
117-
test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act
114+
test_must_fail git push --porcelain dst master:refs/heads/test >act &&
115+
test_cmp exp act
118116
'
119117

120118
cat >bogus-commit <<\EOF

0 commit comments

Comments
 (0)