Skip to content

Commit 865c762

Browse files
10ne1gitster
authored andcommitted
reference-transaction: use hook API instead of run-command
Convert the reference-transaction hook to the new hook API, so it doesn't need to set up a struct child_process, call find_hook or toggle the pipe signals. The stdin feed callback is processing one ref update per call. I haven't noticed any performance degradation due to this, however we can batch as many we want in each call, to ensure a good pipe throughtput (i.e. the child does not wait after stdin). Helped-by: Emily Shaffer <nasamuffin@google.com> Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 9151f05 commit 865c762

File tree

1 file changed

+53
-48
lines changed

1 file changed

+53
-48
lines changed

refs.c

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,68 +2405,73 @@ static int ref_update_reject_duplicates(struct string_list *refnames,
24052405
return 0;
24062406
}
24072407

2408-
static int run_transaction_hook(struct ref_transaction *transaction,
2409-
const char *state)
2408+
struct transaction_feed_cb_data {
2409+
size_t index;
2410+
struct strbuf buf;
2411+
};
2412+
2413+
static int transaction_hook_feed_stdin(int hook_stdin_fd, void *pp_cb, void *pp_task_cb UNUSED)
24102414
{
2411-
struct child_process proc = CHILD_PROCESS_INIT;
2412-
struct strbuf buf = STRBUF_INIT;
2413-
const char *hook;
2414-
int ret = 0;
2415+
struct hook_cb_data *hook_cb = pp_cb;
2416+
struct run_hooks_opt *opt = hook_cb->options;
2417+
struct ref_transaction *transaction = opt->feed_pipe_ctx;
2418+
struct transaction_feed_cb_data *feed_cb_data = opt->feed_pipe_cb_data;
2419+
struct strbuf *buf = &feed_cb_data->buf;
2420+
struct ref_update *update;
2421+
size_t i = feed_cb_data->index++;
2422+
int ret;
24152423

2416-
hook = find_hook(transaction->ref_store->repo, "reference-transaction");
2417-
if (!hook)
2418-
return ret;
2424+
if (i >= transaction->nr)
2425+
return 1; /* No more refs to process */
24192426

2420-
strvec_pushl(&proc.args, hook, state, NULL);
2421-
proc.in = -1;
2422-
proc.stdout_to_stderr = 1;
2423-
proc.trace2_hook_name = "reference-transaction";
2427+
update = transaction->updates[i];
24242428

2425-
ret = start_command(&proc);
2426-
if (ret)
2427-
return ret;
2429+
if (update->flags & REF_LOG_ONLY)
2430+
return 0;
24282431

2429-
sigchain_push(SIGPIPE, SIG_IGN);
2432+
strbuf_reset(buf);
24302433

2431-
for (size_t i = 0; i < transaction->nr; i++) {
2432-
struct ref_update *update = transaction->updates[i];
2434+
if (!(update->flags & REF_HAVE_OLD))
2435+
strbuf_addf(buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
2436+
else if (update->old_target)
2437+
strbuf_addf(buf, "ref:%s ", update->old_target);
2438+
else
2439+
strbuf_addf(buf, "%s ", oid_to_hex(&update->old_oid));
24332440

2434-
if (update->flags & REF_LOG_ONLY)
2435-
continue;
2441+
if (!(update->flags & REF_HAVE_NEW))
2442+
strbuf_addf(buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
2443+
else if (update->new_target)
2444+
strbuf_addf(buf, "ref:%s ", update->new_target);
2445+
else
2446+
strbuf_addf(buf, "%s ", oid_to_hex(&update->new_oid));
24362447

2437-
strbuf_reset(&buf);
2448+
strbuf_addf(buf, "%s\n", update->refname);
24382449

2439-
if (!(update->flags & REF_HAVE_OLD))
2440-
strbuf_addf(&buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
2441-
else if (update->old_target)
2442-
strbuf_addf(&buf, "ref:%s ", update->old_target);
2443-
else
2444-
strbuf_addf(&buf, "%s ", oid_to_hex(&update->old_oid));
2450+
ret = write_in_full(hook_stdin_fd, buf->buf, buf->len);
2451+
if (ret < 0 && errno != EPIPE)
2452+
return ret;
24452453

2446-
if (!(update->flags & REF_HAVE_NEW))
2447-
strbuf_addf(&buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
2448-
else if (update->new_target)
2449-
strbuf_addf(&buf, "ref:%s ", update->new_target);
2450-
else
2451-
strbuf_addf(&buf, "%s ", oid_to_hex(&update->new_oid));
2454+
return 0; /* no more input to feed */
2455+
}
2456+
2457+
static int run_transaction_hook(struct ref_transaction *transaction,
2458+
const char *state)
2459+
{
2460+
struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
2461+
struct transaction_feed_cb_data feed_ctx = { 0 };
2462+
int ret = 0;
24522463

2453-
strbuf_addf(&buf, "%s\n", update->refname);
2464+
strvec_push(&opt.args, state);
24542465

2455-
if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
2456-
if (errno != EPIPE) {
2457-
/* Don't leak errno outside this API */
2458-
errno = 0;
2459-
ret = -1;
2460-
}
2461-
break;
2462-
}
2463-
}
2466+
opt.feed_pipe = transaction_hook_feed_stdin;
2467+
opt.feed_pipe_ctx = transaction;
2468+
opt.feed_pipe_cb_data = &feed_ctx;
24642469

2465-
close(proc.in);
2466-
sigchain_pop(SIGPIPE);
2467-
strbuf_release(&buf);
2470+
strbuf_init(&feed_ctx.buf, 0);
2471+
2472+
ret = run_hooks_opt(transaction->ref_store->repo, "reference-transaction", &opt);
24682473

2469-
ret |= finish_command(&proc);
2474+
strbuf_release(&feed_ctx.buf);
24702475
return ret;
24712476
}
24722477

0 commit comments

Comments
 (0)