summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--run-command.c34
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)