git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] add post-fetch hook

From
Joey Hess <joey@kitenet.net>
Date
Dec 28, 2011, 19:30 UTC
Message-ID
<20111228193008.GB17521@gnu.kitenet.net>
In-Reply-To
<4EFA3833.80409@kdbg.org>
Johannes Sixt wrote:
Show 11 quoted lines
> If I read the loop below correctly, you should be able to run it using
> only the functions sha1_to_hex(), strlen() and write_in_full(). This
> would avoid any problems with concurrent calls to xmalloc().
> 
> > +	int ret;
> > +
> > +	for (ref = post_fetch_hook_refs; ref; ref = ref->next) {
> > +		strbuf_addstr(&buf, sha1_to_hex(ref->old_sha1));
> 
> sha1_to_hex() works with a static buffer. Are you certain that it is not
> called concurrently in the main thread?
Thanks very much for pointing that thread-unsafty out.

Based on that, my current thinking for a generic hook interface is that, rather than the caller providing an arbitrary "feeder" function that gets run async, the caller should provide a function that generates a strbuf containing the stdout for the hook, and then a very simple async writer can handle the actual writing.

static int feed_hook(int in, int out, void *data)
{
        struct strbuf *buf = data;
        return write_in_full(out, buf->buf, buf->len) != buf->len;
}
(I assume that write_in_full is safe to be run async?)

I am working on a patch that will involve adding a hook_complex() and changing hook() to be implemented in terms of it. The header for that is included below, you should get a very good idea of how it will work from the data structure.

/*
 * This data structure controls how a hook is run.
 */
struct hook {
	/* The name of the hook being run. */
	const char *name;
	/* Parameters to pass to the hook program, not including the name
	 * of the hook. May be NULL. */
	struct argv_array *argv_array;
	/* Pathname to an index file to use, or NULL if the hook
	 * uses the default index file or no index is needed. */
	const char *index_file;
	/*
	 * An arbitrary data structure, can be populated and modified to
	 * communicate between the feeder, reader, and caller of the hook.
	 */
	void *data;
	/* 
	 * A hook can optionally not consume all of its stdin.
	 * If partial_stdin is 0, it is an error for some stdin not
	 * to be consumed.
	 */
	int partial_stdin;
	/* 
	 * feeder populates a strbuf with the content to send to the
	 * hook on its standard input.
	 *
	 * May be NULL, if the hook does not consume standard input.
	 *
	 * Note that feeder might be run more than once, if multiple
	 * programs are run as part of a single hook. It should avoid
	 * taking any actions except for reading from data and generating
	 * the strbuf. It will *not* be run async, and need not worry
	 * about contending with other threads.
	 */
	struct strbuf *(*feeder)(struct hook *hook);
	/*
	 * reader processes the hook's standard output from the handle,
	 * returning 0 on success, non-zero on failure.
	 *
	 * May be NULL, if the hook's stdin is not processed. (It will
	 * instead be redirected to stderr.)
	 *
	 * Note that reader might be run more than once, if multiple
	 * programs are run as part of a single hook. It should avoid
	 * taking any actions except for reading from the input handle,
	 * changing the content of data, and printing any necessary
	 * warnings. It will *not* be run async, and need not worry
	 * about contending with other threads.
	 */
	int (*reader)(struct hook *hook, int handle);
};
extern int run_hook(const char *index_file, const char *name, ...);
extern int run_hook_complex(struct hook *hook);
This design allows for a future where multiple scripts get run for a
single hook. In that case, the feeder and reader functions would get
called repeatedly in a loop, with a data flow like this, where the
reader modifies hook.data, providing the next call of the feeder with
the new data read from the hook script:
    feeder | hook_script_1 | reader | feeder | hook_script_2 | reader
-- 
see shy jo
Previous: Johannes Sixt
Message 16 of 16 in “add post-fetch hook”
  1. add post-fetch hookJoey Hess, Dec 24, 2011
  2. Junio C HamanoDec 25, 2011
  3. Joey HessDec 25, 2011
  4. Junio C HamanoDec 25, 2011
  5. Jakub NarebskiDec 25, 2011
  6. Joey HessDec 25, 2011
  7. Junio C HamanoDec 26, 2011
  8. Joey HessDec 25, 2011
  9. add post-fetch hookJoey Hess, Dec 26, 2011
  10. Junio C HamanoDec 26, 2011
  11. Joey HessDec 26, 2011
  12. Junio C HamanoDec 27, 2011
  13. Joey HessDec 27, 2011
  14. Junio C HamanoDec 27, 2011
  15. Johannes SixtDec 27, 2011
  16. Joey HessDec 28, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.