Merge branch 'jk/epipe-in-async'
Handling of errors while writing into our internal asynchronous process has been made more robust, which reduces flakiness in our tests. * jk/epipe-in-async: t5504: handle expected output from SIGPIPE death test_must_fail: report number of unexpected signal fetch-pack: ignore SIGPIPE in sideband demuxer write_or_die: handle EPIPE in async threads
This commit is contained in:
commit
8ef250c559
@ -15,6 +15,7 @@
|
||||
#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;
|
||||
@ -671,9 +672,12 @@ static int everything_local(struct fetch_pack_args *args,
|
||||
static int sideband_demux(int in, int out, void *data)
|
||||
{
|
||||
int *xd = data;
|
||||
int ret;
|
||||
|
||||
int ret = recv_sideband("fetch-pack", xd[0], out);
|
||||
sigchain_push(SIGPIPE, SIG_IGN);
|
||||
ret = recv_sideband("fetch-pack", xd[0], out);
|
||||
close(out);
|
||||
sigchain_pop(SIGPIPE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -625,6 +625,11 @@ int in_async(void)
|
||||
return !pthread_equal(main_thread, pthread_self());
|
||||
}
|
||||
|
||||
void NORETURN async_exit(int code)
|
||||
{
|
||||
pthread_exit((void *)(intptr_t)code);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static struct {
|
||||
@ -670,6 +675,11 @@ int in_async(void)
|
||||
return process_is_async;
|
||||
}
|
||||
|
||||
void NORETURN async_exit(int code)
|
||||
{
|
||||
exit(code);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int start_async(struct async *async)
|
||||
|
@ -121,6 +121,7 @@ struct async {
|
||||
int start_async(struct async *async);
|
||||
int finish_async(struct async *async);
|
||||
int in_async(void);
|
||||
void NORETURN async_exit(int code);
|
||||
|
||||
/**
|
||||
* This callback should initialize the child process and preload the
|
||||
|
@ -101,7 +101,10 @@ test_expect_success 'push with receive.fsckobjects' '
|
||||
git config transfer.fsckobjects false
|
||||
) &&
|
||||
test_must_fail ok=sigpipe 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' '
|
||||
|
@ -617,7 +617,7 @@ test_must_fail () {
|
||||
return 0
|
||||
elif test $exit_code -gt 129 && test $exit_code -le 192
|
||||
then
|
||||
echo >&2 "test_must_fail: died by signal: $*"
|
||||
echo >&2 "test_must_fail: died by signal $(($exit_code - 128)): $*"
|
||||
return 1
|
||||
elif test $exit_code -eq 127
|
||||
then
|
||||
|
@ -1,8 +1,12 @@
|
||||
#include "cache.h"
|
||||
#include "run-command.h"
|
||||
|
||||
static void check_pipe(int err)
|
||||
{
|
||||
if (err == EPIPE) {
|
||||
if (in_async())
|
||||
async_exit(141);
|
||||
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
raise(SIGPIPE);
|
||||
/* Should never happen, but just in case... */
|
||||
|
Loading…
Reference in New Issue
Block a user