52
return path.buf;
53
}
54
55
-static void hook_clear(struct hook *h, hook_data_free_fn cb_data_free)
55
+void hook_free(void *p, const char *str UNUSED)
56
{
57
+ struct hook *h = p;
58
+
59
if (!h)
60
return;
61
66
free((void *)h->u.configured.command);
67
}
68
67
- if (cb_data_free)
68
- cb_data_free(h->feed_pipe_cb_data);
69
+ if (h->data_free && h->feed_pipe_cb_data)
70
+ h->data_free(h->feed_pipe_cb_data);
71
72
free(h);
73
}
74
73
-void hook_list_clear(struct string_list *hooks, hook_data_free_fn cb_data_free)
74
-{
75
- struct string_list_item *item;
76
-
77
- for_each_string_list_item(item, hooks)
78
- hook_clear(item->util, cb_data_free);
79
-
80
- string_list_clear(hooks, 0);
81
-}
82
-
75
/* Helper to detect and add default "traditional" hooks from the hookdir. */
76
static void list_hooks_add_default(struct repository *r, const char *hookname,
77
struct string_list *hook_list,
92
if (options && options->dir)
93
hook_path = absolute_path(hook_path);
94
103
- /* Setup per-hook internal state cb data */
104
- if (options && options->feed_pipe_cb_data_alloc)
95
+ /*
96
+ * Setup per-hook internal state callback data.
97
+ * When provided, the alloc/free callbacks are always provided
98
+ * together, so use them to alloc/free the internal hook state.
99
+ */
100
+ if (options && options->feed_pipe_cb_data_alloc) {
101
h->feed_pipe_cb_data = options->feed_pipe_cb_data_alloc(options->feed_pipe_ctx);
102
+ h->data_free = options->feed_pipe_cb_data_free;
103
+ }
104
105
h->kind = HOOK_TRADITIONAL;
106
h->u.traditional.path = xstrdup(hook_path);
314
315
CALLOC_ARRAY(hook, 1);
316
319
- if (options && options->feed_pipe_cb_data_alloc)
317
+ /*
318
+ * When provided, the alloc/free callbacks are always provided
319
+ * together, so use them to alloc/free the internal hook state.
320
+ */
321
+ if (options && options->feed_pipe_cb_data_alloc) {
322
hook->feed_pipe_cb_data =
323
options->feed_pipe_cb_data_alloc(
324
options->feed_pipe_ctx);
325
+ hook->data_free = options->feed_pipe_cb_data_free;
326
+ }
327
328
hook->kind = HOOK_CONFIGURED;
329
hook->u.configured.friendly_name = xstrdup(friendly_name);
366
{
367
struct string_list *hooks = list_hooks(r, name, NULL);
368
int exists = hooks->nr > 0;
365
- hook_list_clear(hooks, NULL);
369
+ string_list_clear_func(hooks, hook_free);
370
free(hooks);
371
return exists;
372
}
520
run_processes_parallel(&opts);
521
ret = cb_data.rc;
522
cleanup:
519
- hook_list_clear(cb_data.hook_command_list, options->feed_pipe_cb_data_free);
523
+ string_list_clear_func(cb_data.hook_command_list, hook_free);
524
free(cb_data.hook_command_list);
525
run_hooks_opt_clear(options);
526
return ret;