diff options
-rw-r--r-- | run-command.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/run-command.c b/run-command.c index 77aefff2e2..66cc4bfa57 100644 --- a/run-command.c +++ b/run-command.c @@ -448,12 +448,35 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const } #ifdef ASYNC_AS_THREAD +static pthread_t main_thread; +static int main_thread_set; +static pthread_key_t async_key; + static void *run_thread(void *data) { struct async *async = data; + + pthread_setspecific(async_key, async); + intptr_t ret = async->proc(async->proc_in, async->proc_out, async->data); return (void *)ret; } + +static NORETURN void die_async(const char *err, va_list params) +{ + vreportf("fatal: ", err, params); + + if (!pthread_equal(main_thread, pthread_self())) { + struct async *async = pthread_getspecific(async_key); + if (async->proc_in >= 0) + close(async->proc_in); + if (async->proc_out >= 0) + close(async->proc_out); + pthread_exit((void *)128); + } + + exit(128); +} #endif int start_async(struct async *async) @@ -525,6 +548,17 @@ int start_async(struct async *async) else if (async->out) close(async->out); #else + if (!main_thread_set) { + /* + * We assume that the first time that start_async is called + * it is from the main thread. + */ + main_thread_set = 1; + main_thread = pthread_self(); + pthread_key_create(&async_key, NULL); + set_die_routine(die_async); + } + if (proc_in >= 0) set_cloexec(proc_in); if (proc_out >= 0) |