Skip to content

Commit

Permalink
fetch-pack: Prepare for a side-band demultiplexer in a thread.
Browse files Browse the repository at this point in the history
get_pack() receives a pair of file descriptors that communicate with
upload-pack at the remote end. In order to support the case where the
side-band demultiplexer runs in a thread, and, hence, in the same process
as the main routine, we must not close the readable file descriptor early.

The handling of the readable fd is changed in the case where upload-pack
supports side-band communication: The old code closed the fd after it was
inherited to the side-band demultiplexer process. Now we do not close it.
The caller (do_fetch_pack) will close it later anyway. The demultiplexer
is the only reader, it does not matter that the fd remains open in the
main process as well as in unpack-objects/index-pack, which inherits it.

The writable fd is not needed in get_pack(), hence, the old code closed
the fd. For symmetry with the readable fd, we now do not close it; the
caller (do_fetch_pack) will close it later anyway. Therefore, the new
behavior is that the channel now remains open during the entire
conversation, but this has no ill effects because upload-pack does not read
from it once it has begun to send the pack data. For the same reason it
does not matter that the writable fd is now inherited to the demultiplexer
and unpack-objects/index-pack processes.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Johannes Sixt authored and Junio C Hamano committed Nov 18, 2007
1 parent 5f9ffff commit 1f759ee
Showing 1 changed file with 16 additions and 26 deletions.
42 changes: 16 additions & 26 deletions builtin-fetch-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,42 +462,33 @@ static int sideband_demux(int fd, void *data)
{
int *xd = data;

close(xd[1]);
return recv_sideband("fetch-pack", xd[0], fd, 2);
}

static void setup_sideband(int fd[2], int xd[2], struct async *demux)
{
if (!use_sideband) {
fd[0] = xd[0];
fd[1] = xd[1];
return;
}
/* xd[] is talking with upload-pack; subprocess reads from
* xd[0], spits out band#2 to stderr, and feeds us band#1
* through demux->out.
*/
demux->proc = sideband_demux;
demux->data = xd;
if (start_async(demux))
die("fetch-pack: unable to fork off sideband demultiplexer");
close(xd[0]);
fd[0] = demux->out;
fd[1] = xd[1];
}

static int get_pack(int xd[2], char **pack_lockfile)
{
struct async demux;
int fd[2];
const char *argv[20];
char keep_arg[256];
char hdr_arg[256];
const char **av;
int do_keep = args.keep_pack;
struct child_process cmd;

setup_sideband(fd, xd, &demux);
memset(&demux, 0, sizeof(demux));
if (use_sideband) {
/* xd[] is talking with upload-pack; subprocess reads from
* xd[0], spits out band#2 to stderr, and feeds us band#1
* through demux->out.
*/
demux.proc = sideband_demux;
demux.data = xd;
if (start_async(&demux))
die("fetch-pack: unable to fork off sideband"
" demultiplexer");
}
else
demux.out = xd[0];

memset(&cmd, 0, sizeof(cmd));
cmd.argv = argv;
Expand All @@ -506,7 +497,7 @@ static int get_pack(int xd[2], char **pack_lockfile)
if (!args.keep_pack && unpack_limit) {
struct pack_header header;

if (read_pack_header(fd[0], &header))
if (read_pack_header(demux.out, &header))
die("protocol error: bad pack header");
snprintf(hdr_arg, sizeof(hdr_arg), "--pack_header=%u,%u",
ntohl(header.hdr_version), ntohl(header.hdr_entries));
Expand Down Expand Up @@ -542,11 +533,10 @@ static int get_pack(int xd[2], char **pack_lockfile)
*av++ = hdr_arg;
*av++ = NULL;

cmd.in = fd[0];
cmd.in = demux.out;
cmd.git_cmd = 1;
if (start_command(&cmd))
die("fetch-pack: unable to fork off %s", argv[0]);
close(fd[1]);
if (do_keep && pack_lockfile)
*pack_lockfile = index_pack_lockfile(cmd.out);

Expand Down

0 comments on commit 1f759ee

Please sign in to comment.