run-command: support custom fd-set in async

This patch adds the possibility to supply a set of non-0 file
descriptors for async process communication instead of the
default-created pipe.

Additionally, we now support bi-directional communiction with the
async procedure, by giving the async function both read and write
file descriptors.

To retain compatiblity and similar "API feel" with start_command,
we require start_async callers to set .out = -1 to get a readable
file descriptor.  If either of .in or .out is 0, we supply no file
descriptor to the async process.

[sp: Note: Erik started this patch, and a huge bulk of it is
     his work.  All bugs were introduced later by Shawn.]

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Erik Faye-Lund
2010-02-05 12:57:38 -08:00
committed by Junio C Hamano
parent 4f41b61148
commit ae6a5609c0
7 changed files with 131 additions and 37 deletions

View File

@ -64,8 +64,8 @@ The functions above do the following:
`start_async`::
Run a function asynchronously. Takes a pointer to a `struct
async` that specifies the details and returns a pipe FD
from which the caller reads. See below for details.
async` that specifies the details and returns a set of pipe FDs
for communication with the function. See below for details.
`finish_async`::
@ -180,17 +180,47 @@ The caller:
struct async variable;
2. initializes .proc and .data;
3. calls start_async();
4. processes the data by reading from the fd in .out;
5. closes .out;
4. processes communicates with proc through .in and .out;
5. closes .in and .out;
6. calls finish_async().
The members .in, .out are used to provide a set of fd's for
communication between the caller and the callee as follows:
. Specify 0 to have no file descriptor passed. The callee will
receive -1 in the corresponding argument.
. Specify < 0 to have a pipe allocated; start_async() replaces
with the pipe FD in the following way:
.in: Returns the writable pipe end into which the caller
writes; the readable end of the pipe becomes the function's
in argument.
.out: Returns the readable pipe end from which the caller
reads; the writable end of the pipe becomes the function's
out argument.
The caller of start_async() must close the returned FDs after it
has completed reading from/writing from them.
. Specify a file descriptor > 0 to be used by the function:
.in: The FD must be readable; it becomes the function's in.
.out: The FD must be writable; it becomes the function's out.
The specified FD is closed by start_async(), even if it fails to
run the function.
The function pointer in .proc has the following signature:
int proc(int fd, void *data);
int proc(int in, int out, void *data);
. fd specifies a writable file descriptor to which the function must
write the data that it produces. The function *must* close this
descriptor before it returns.
. in, out specifies a set of file descriptors to which the function
must read/write the data that it needs/produces. The function
*must* close these descriptors before it returns. A descriptor
may be -1 if the caller did not configure a descriptor for that
direction.
. data is the value that the caller has specified in the .data member
of struct async.
@ -205,8 +235,8 @@ because this facility is implemented by a pipe to a forked process on
UNIX, but by a thread in the same address space on Windows:
. It cannot change the program's state (global variables, environment,
etc.) in a way that the caller notices; in other words, .out is the
only communication channel to the caller.
etc.) in a way that the caller notices; in other words, .in and .out
are the only communication channels to the caller.
. It must not change the program's state that the caller of the
facility also uses.