@matheusbsbs / matheus-bagliano / commits / 618ebe9ff9
Fork 0

Windows: Implement asynchronous functions as threads.

In upload-pack we must explicitly close the output channel of rev-list. (On Unix, the channel is closed automatically because process that runs rev-list terminates.) Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>

Johannes Sixt committed Dec 8, 2007 at 22:19 UTC 618ebe9ff997d27714487c4a4232720be240badc
3 files changed +35 -1
run-command.c
+28 -1
@@ -288,13 +288,23 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const
288 return run_command(&cmd);
289 }
290
291 +#ifdef __MINGW32__
292 +static __stdcall unsigned run_thread(void *data)
293 +{
294 + struct async *async = data;
295 + return async->proc(async->fd_for_proc, async->data);
296 +}
297 +#endif
298 +
299 int start_async(struct async *async)
300 {
301 int pipe_out[2];
302
303 if (pipe(pipe_out) < 0)
304 return error("cannot create pipe: %s", strerror(errno));
305 + async->out = pipe_out[0];
306
307 +#ifndef __MINGW32__
308 async->pid = fork();
309 if (async->pid < 0) {
310 error("fork (async) failed: %s", strerror(errno));
@@ -305,16 +315,33 @@ int start_async(struct async *async)
315 close(pipe_out[0]);
316 exit(!!async->proc(pipe_out[1], async->data));
317 }
308 - async->out = pipe_out[0];
318 close(pipe_out[1]);
319 +#else
320 + async->fd_for_proc = pipe_out[1];
321 + async->tid = (HANDLE) _beginthreadex(NULL, 0, run_thread, async, 0, NULL);
322 + if (!async->tid) {
323 + error("cannot create thread: %s", strerror(errno));
324 + close_pair(pipe_out);
325 + return -1;
326 + }
327 +#endif
328 return 0;
329 }
330
331 int finish_async(struct async *async)
332 {
333 +#ifndef __MINGW32__
334 int ret = 0;
335
336 if (wait_or_whine(async->pid))
337 ret = error("waitpid (async) failed");
338 +#else
339 + DWORD ret = 0;
340 + if (WaitForSingleObject(async->tid, INFINITE) != WAIT_OBJECT_0)
341 + ret = error("waiting for thread failed: %lu", GetLastError());
342 + else if (!GetExitCodeThread(async->tid, &ret))
343 + ret = error("cannot get thread exit code: %lu", GetLastError());
344 + CloseHandle(async->tid);
345 +#endif
346 return ret;
347 }
run-command.h
+5
@@ -76,7 +76,12 @@ struct async {
76 int (*proc)(int fd, void *data);
77 void *data;
78 int out; /* caller reads from here and closes it */
79 +#ifndef __MINGW32__
80 pid_t pid;
81 +#else
82 + HANDLE tid;
83 + int fd_for_proc;
84 +#endif
85 };
86
87 int start_async(struct async *async);
upload-pack.c
+2
@@ -135,6 +135,8 @@ static int do_rev_list(int fd, void *create_full_pack)
135 die("revision walk setup failed");
136 mark_edges_uninteresting(revs.commits, &revs, show_edge);
137 traverse_commit_list(&revs, show_commit, show_object);
138 + fflush(pack_pipe);
139 + fclose(pack_pipe);
140 return 0;
141 }
142