mirror of
https://github.com/git/git.git
synced 2026-04-02 04:50:12 +02:00
Implement thread-specific die() routines; use one in start_async().
This commit is contained in:
committed by
Johannes Sixt
parent
4eb0463971
commit
85763c86da
@@ -293,9 +293,22 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
static int close_fd = -1;
|
||||||
|
NORETURN void die_from_thread(const char *err, va_list params)
|
||||||
|
{
|
||||||
|
vreport("fatal: ", err, params);
|
||||||
|
if (close_fd >= 0)
|
||||||
|
close(close_fd);
|
||||||
|
_endthreadex(128);
|
||||||
|
exit(128); /* silence compiler */
|
||||||
|
}
|
||||||
|
|
||||||
static __stdcall unsigned run_thread(void *data)
|
static __stdcall unsigned run_thread(void *data)
|
||||||
{
|
{
|
||||||
struct async *async = data;
|
struct async *async = data;
|
||||||
|
close_fd = async->fd_for_proc;
|
||||||
|
extern NORETURN void die_from_thread(const char *err, va_list params);
|
||||||
|
set_die_routine(die_from_thread);
|
||||||
return async->proc(async->fd_for_proc, async->data);
|
return async->proc(async->fd_for_proc, async->data);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -349,6 +362,9 @@ int finish_async(struct async *async)
|
|||||||
else if (!GetExitCodeThread(async->tid, &ret))
|
else if (!GetExitCodeThread(async->tid, &ret))
|
||||||
ret = error("cannot get thread exit code: %lu", GetLastError());
|
ret = error("cannot get thread exit code: %lu", GetLastError());
|
||||||
CloseHandle(async->tid);
|
CloseHandle(async->tid);
|
||||||
|
if (ret)
|
||||||
|
/* test suite tests for this string */
|
||||||
|
error("waitpid (async) failed");
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,9 +48,6 @@ valgrind:
|
|||||||
GIT_SKIP_TESTS := $(GIT_SKIP_TESTS_LOCAL)
|
GIT_SKIP_TESTS := $(GIT_SKIP_TESTS_LOCAL)
|
||||||
# git am does not treat absolute path to mbox file correctly
|
# git am does not treat absolute path to mbox file correctly
|
||||||
GIT_SKIP_TESTS += t4150.18
|
GIT_SKIP_TESTS += t4150.18
|
||||||
# git upload-pack does not write an error message in this case
|
|
||||||
# (reason unknown; seems to be a race condition)
|
|
||||||
GIT_SKIP_TESTS += t5530.6
|
|
||||||
# output contains CRLF (I think)
|
# output contains CRLF (I think)
|
||||||
GIT_SKIP_TESTS += t7401.14
|
GIT_SKIP_TESTS += t7401.14
|
||||||
# output contains CRLF (I think)
|
# output contains CRLF (I think)
|
||||||
|
|||||||
32
usage.c
32
usage.c
@@ -34,16 +34,38 @@ static void warn_builtin(const char *warn, va_list params)
|
|||||||
vreport("warning: ", warn, params);
|
vreport("warning: ", warn, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void (*die_fn_t)(const char *err, va_list params) NORETURN;
|
||||||
|
|
||||||
|
static DWORD tls_index;
|
||||||
|
|
||||||
|
static void tls_init(void) __attribute__((constructor));
|
||||||
|
static void tls_init(void)
|
||||||
|
{
|
||||||
|
tls_index = TlsAlloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct routines {
|
||||||
|
die_fn_t die_routine;
|
||||||
|
};
|
||||||
/* If we are in a dlopen()ed .so write to a global variable would segfault
|
/* If we are in a dlopen()ed .so write to a global variable would segfault
|
||||||
* (ugh), so keep things static. */
|
* (ugh), so keep things static. */
|
||||||
static void (*usage_routine)(const char *err) NORETURN = usage_builtin;
|
static void (*usage_routine)(const char *err) NORETURN = usage_builtin;
|
||||||
static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;
|
|
||||||
static void (*error_routine)(const char *err, va_list params) = error_builtin;
|
static void (*error_routine)(const char *err, va_list params) = error_builtin;
|
||||||
static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
|
static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
|
||||||
|
|
||||||
void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN)
|
void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN)
|
||||||
{
|
{
|
||||||
die_routine = routine;
|
struct routines *r = TlsGetValue(tls_index);
|
||||||
|
if (r == NULL) {
|
||||||
|
/* avoid die()! */
|
||||||
|
r = calloc(sizeof(*r), 1);
|
||||||
|
if (r == NULL) {
|
||||||
|
fprintf(stderr, "cannot allocate thread-local storage");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TlsSetValue(tls_index, r);
|
||||||
|
}
|
||||||
|
r->die_routine = routine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage(const char *err)
|
void usage(const char *err)
|
||||||
@@ -54,9 +76,13 @@ void usage(const char *err)
|
|||||||
void die(const char *err, ...)
|
void die(const char *err, ...)
|
||||||
{
|
{
|
||||||
va_list params;
|
va_list params;
|
||||||
|
struct routines *r = TlsGetValue(tls_index);
|
||||||
|
|
||||||
va_start(params, err);
|
va_start(params, err);
|
||||||
die_routine(err, params);
|
if (r == NULL || r->die_routine == NULL)
|
||||||
|
die_builtin(err, params);
|
||||||
|
else
|
||||||
|
r->die_routine(err, params);
|
||||||
va_end(params);
|
va_end(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user