зеркало из https://github.com/microsoft/git.git
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:
Коммит
c555e529ac
|
@ -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; }
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -116,6 +116,7 @@ struct async {
|
|||
int proc_in;
|
||||
int proc_out;
|
||||
#endif
|
||||
int isolate_sigpipe;
|
||||
};
|
||||
|
||||
int start_async(struct async *async);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче