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
This commit is contained in:
@ -142,6 +142,7 @@ static inline int fcntl(int fd, int cmd, ...)
|
|||||||
#define sigemptyset(x) (void)0
|
#define sigemptyset(x) (void)0
|
||||||
static inline int sigaddset(sigset_t *set, int signum)
|
static inline int sigaddset(sigset_t *set, int signum)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
#define SIG_BLOCK 0
|
||||||
#define SIG_UNBLOCK 0
|
#define SIG_UNBLOCK 0
|
||||||
static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
|
static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
@ -104,4 +104,11 @@ static inline void *pthread_getspecific(pthread_key_t key)
|
|||||||
return TlsGetValue(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 */
|
#endif /* PTHREAD_H */
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "prio-queue.h"
|
#include "prio-queue.h"
|
||||||
#include "sha1-array.h"
|
#include "sha1-array.h"
|
||||||
#include "sigchain.h"
|
|
||||||
|
|
||||||
static int transfer_unpack_limit = -1;
|
static int transfer_unpack_limit = -1;
|
||||||
static int fetch_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 *xd = data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sigchain_push(SIGPIPE, SIG_IGN);
|
|
||||||
ret = recv_sideband("fetch-pack", xd[0], out);
|
ret = recv_sideband("fetch-pack", xd[0], out);
|
||||||
close(out);
|
close(out);
|
||||||
sigchain_pop(SIGPIPE);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,6 +698,7 @@ static int get_pack(struct fetch_pack_args *args,
|
|||||||
demux.proc = sideband_demux;
|
demux.proc = sideband_demux;
|
||||||
demux.data = xd;
|
demux.data = xd;
|
||||||
demux.out = -1;
|
demux.out = -1;
|
||||||
|
demux.isolate_sigpipe = 1;
|
||||||
if (start_async(&demux))
|
if (start_async(&demux))
|
||||||
die("fetch-pack: unable to fork off sideband"
|
die("fetch-pack: unable to fork off sideband"
|
||||||
" demultiplexer");
|
" demultiplexer");
|
||||||
|
@ -590,6 +590,16 @@ static void *run_thread(void *data)
|
|||||||
struct async *async = data;
|
struct async *async = data;
|
||||||
intptr_t ret;
|
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);
|
pthread_setspecific(async_key, async);
|
||||||
ret = async->proc(async->proc_in, async->proc_out, async->data);
|
ret = async->proc(async->proc_in, async->proc_out, async->data);
|
||||||
return (void *)ret;
|
return (void *)ret;
|
||||||
|
@ -116,6 +116,7 @@ struct async {
|
|||||||
int proc_in;
|
int proc_in;
|
||||||
int proc_out;
|
int proc_out;
|
||||||
#endif
|
#endif
|
||||||
|
int isolate_sigpipe;
|
||||||
};
|
};
|
||||||
|
|
||||||
int start_async(struct async *async);
|
int start_async(struct async *async);
|
||||||
|
@ -518,6 +518,7 @@ int send_pack(struct send_pack_args *args,
|
|||||||
demux.proc = sideband_demux;
|
demux.proc = sideband_demux;
|
||||||
demux.data = fd;
|
demux.data = fd;
|
||||||
demux.out = -1;
|
demux.out = -1;
|
||||||
|
demux.isolate_sigpipe = 1;
|
||||||
if (start_async(&demux))
|
if (start_async(&demux))
|
||||||
die("send-pack: unable to fork off sideband demultiplexer");
|
die("send-pack: unable to fork off sideband demultiplexer");
|
||||||
in = demux.out;
|
in = demux.out;
|
||||||
@ -531,8 +532,10 @@ int send_pack(struct send_pack_args *args,
|
|||||||
close(out);
|
close(out);
|
||||||
if (git_connection_is_socket(conn))
|
if (git_connection_is_socket(conn))
|
||||||
shutdown(fd[0], SHUT_WR);
|
shutdown(fd[0], SHUT_WR);
|
||||||
if (use_sideband)
|
if (use_sideband) {
|
||||||
|
close(demux.out);
|
||||||
finish_async(&demux);
|
finish_async(&demux);
|
||||||
|
}
|
||||||
fd[1] = -1;
|
fd[1] = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -551,11 +554,11 @@ int send_pack(struct send_pack_args *args,
|
|||||||
packet_flush(out);
|
packet_flush(out);
|
||||||
|
|
||||||
if (use_sideband && cmds_sent) {
|
if (use_sideband && cmds_sent) {
|
||||||
|
close(demux.out);
|
||||||
if (finish_async(&demux)) {
|
if (finish_async(&demux)) {
|
||||||
error("error in sideband demultiplexer");
|
error("error in sideband demultiplexer");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
close(demux.out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -100,11 +100,8 @@ test_expect_success 'push with receive.fsckobjects' '
|
|||||||
git config receive.fsckobjects true &&
|
git config receive.fsckobjects true &&
|
||||||
git config transfer.fsckobjects false
|
git config transfer.fsckobjects false
|
||||||
) &&
|
) &&
|
||||||
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
|
||||||
test_cmp exp act ||
|
|
||||||
! test -s act
|
|
||||||
}
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'push with transfer.fsckobjects' '
|
test_expect_success 'push with transfer.fsckobjects' '
|
||||||
@ -114,7 +111,8 @@ test_expect_success 'push with transfer.fsckobjects' '
|
|||||||
cd dst &&
|
cd dst &&
|
||||||
git config transfer.fsckobjects true
|
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
|
cat >bogus-commit <<\EOF
|
||||||
|
Reference in New Issue
Block a user