summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--run-command.c41
-rw-r--r--run-command.h8
3 files changed, 34 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index 52f2cc040b..2fe52f8163 100644
--- a/Makefile
+++ b/Makefile
@@ -979,6 +979,7 @@ ifeq ($(uname_S),Windows)
NO_CURL = YesPlease
NO_PYTHON = YesPlease
BLK_SHA1 = YesPlease
+ ASYNC_AS_THREAD = YesPlease
CC = compat/vcbuild/scripts/clink.pl
AR = compat/vcbuild/scripts/lib.pl
@@ -1030,6 +1031,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
NO_REGEX = YesPlease
NO_PYTHON = YesPlease
BLK_SHA1 = YesPlease
+ ASYNC_AS_THREAD = YesPlease
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
@@ -1342,6 +1344,9 @@ ifdef NO_PTHREADS
else
EXTLIBS += $(PTHREAD_LIBS)
LIB_OBJS += thread-utils.o
+ifdef ASYNC_AS_THREAD
+ BASIC_CFLAGS += -DASYNC_AS_THREAD
+endif
endif
ifdef DIR_HAS_BSD_GROUP_SEMANTICS
diff --git a/run-command.c b/run-command.c
index 0cd7f02ffe..77aefff2e2 100644
--- a/run-command.c
+++ b/run-command.c
@@ -82,6 +82,7 @@ static NORETURN void die_child(const char *err, va_list params)
write(child_err, "\n", 1);
exit(128);
}
+#endif
static inline void set_cloexec(int fd)
{
@@ -89,7 +90,6 @@ static inline void set_cloexec(int fd)
if (flags >= 0)
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
-#endif
static int wait_or_whine(pid_t pid, const char *argv0, int silent_exec_failure)
{
@@ -447,11 +447,12 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const
return run_command(&cmd);
}
-#ifdef WIN32
-static unsigned __stdcall run_thread(void *data)
+#ifdef ASYNC_AS_THREAD
+static void *run_thread(void *data)
{
struct async *async = data;
- return async->proc(async->proc_in, async->proc_out, async->data);
+ intptr_t ret = async->proc(async->proc_in, async->proc_out, async->data);
+ return (void *)ret;
}
#endif
@@ -497,7 +498,7 @@ int start_async(struct async *async)
else
proc_out = -1;
-#ifndef WIN32
+#ifndef ASYNC_AS_THREAD
/* Flush stdio before fork() to avoid cloning buffers */
fflush(NULL);
@@ -524,12 +525,18 @@ int start_async(struct async *async)
else if (async->out)
close(async->out);
#else
+ if (proc_in >= 0)
+ set_cloexec(proc_in);
+ if (proc_out >= 0)
+ set_cloexec(proc_out);
async->proc_in = proc_in;
async->proc_out = proc_out;
- async->tid = (HANDLE) _beginthreadex(NULL, 0, run_thread, async, 0, NULL);
- if (!async->tid) {
- error("cannot create thread: %s", strerror(errno));
- goto error;
+ {
+ int err = pthread_create(&async->tid, NULL, run_thread, async);
+ if (err) {
+ error("cannot create thread: %s", strerror(err));
+ goto error;
+ }
}
#endif
return 0;
@@ -549,17 +556,15 @@ error:
int finish_async(struct async *async)
{
-#ifndef WIN32
- int ret = wait_or_whine(async->pid, "child process", 0);
+#ifndef ASYNC_AS_THREAD
+ return wait_or_whine(async->pid, "child process", 0);
#else
- DWORD ret = 0;
- if (WaitForSingleObject(async->tid, INFINITE) != WAIT_OBJECT_0)
- ret = error("waiting for thread failed: %lu", GetLastError());
- else if (!GetExitCodeThread(async->tid, &ret))
- ret = error("cannot get thread exit code: %lu", GetLastError());
- CloseHandle(async->tid);
+ void *ret = (void *)(intptr_t)(-1);
+
+ if (pthread_join(async->tid, &ret))
+ error("pthread_join failed");
+ return (int)(intptr_t)ret;
#endif
- return ret;
}
int run_hook(const char *index_file, const char *name, ...)
diff --git a/run-command.h b/run-command.h
index 94619f52d9..40db39cec0 100644
--- a/run-command.h
+++ b/run-command.h
@@ -1,6 +1,10 @@
#ifndef RUN_COMMAND_H
#define RUN_COMMAND_H
+#ifdef ASYNC_AS_THREAD
+#include <pthread.h>
+#endif
+
struct child_process {
const char **argv;
pid_t pid;
@@ -74,10 +78,10 @@ struct async {
void *data;
int in; /* caller writes here and closes it */
int out; /* caller reads from here and closes it */
-#ifndef WIN32
+#ifndef ASYNC_AS_THREAD
pid_t pid;
#else
- HANDLE tid;
+ pthread_t tid;
int proc_in;
int proc_out;
#endif