aboutsummaryrefslogtreecommitdiffstats
path: root/filter.c
diff options
context:
space:
mode:
authorGravatar Jason A. Donenfeld <Jason@zx2c4.com>2014-01-13 04:58:21 (JST)
committerGravatar Jason A. Donenfeld <Jason@zx2c4.com>2014-01-14 10:00:07 (JST)
commitd750c7a2c9bb83cfc47c0d74fcee61f0a5042aa9 (patch)
tree51697a3a35b56957e827682d3119bdca4e2684bc /filter.c
parent4bb87cbf17588ec91b46bf0ef0be01672e9be787 (diff)
downloadcgit-d750c7a2c9bb83cfc47c0d74fcee61f0a5042aa9.zip
cgit-d750c7a2c9bb83cfc47c0d74fcee61f0a5042aa9.tar.gz
filter: allow for cleanup hook for filter types
At some point, we're going to want to do lazy deallocation of filters. For example, if we implement lua, we'll want to load the lua runtime once for each filter, even if that filter is called many times. Similarly, for persistent exec filters, we'll want to load it once, despite many open_filter and close_filter calls, and only reap the child process at the end of the cgit process. For this reason, we add here a cleanup function that is called at the end of cgit's main(). Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'filter.c')
-rw-r--r--filter.c90
1 files changed, 63 insertions, 27 deletions
diff --git a/filter.c b/filter.c
index ba66e46..30bc74b 100644
--- a/filter.c
+++ b/filter.c
@@ -13,6 +13,25 @@
13#include <string.h> 13#include <string.h>
14#include <stdlib.h> 14#include <stdlib.h>
15 15
16static inline void reap_filter(struct cgit_filter *filter)
17{
18 if (filter && filter->cleanup)
19 filter->cleanup(filter);
20}
21
22void cgit_cleanup_filters(void)
23{
24 int i;
25 reap_filter(ctx.cfg.about_filter);
26 reap_filter(ctx.cfg.commit_filter);
27 reap_filter(ctx.cfg.source_filter);
28 for (i = 0; i < cgit_repolist.count; ++i) {
29 reap_filter(cgit_repolist.repos[i].about_filter);
30 reap_filter(cgit_repolist.repos[i].commit_filter);
31 reap_filter(cgit_repolist.repos[i].source_filter);
32 }
33}
34
16static int open_exec_filter(struct cgit_filter *base, va_list ap) 35static int open_exec_filter(struct cgit_filter *base, va_list ap)
17{ 36{
18 struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base; 37 struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base;
@@ -67,34 +86,17 @@ static void fprintf_exec_filter(struct cgit_filter *base, FILE *f, const char *p
67 fprintf(f, "%sexec:%s\n", prefix, filter->cmd); 86 fprintf(f, "%sexec:%s\n", prefix, filter->cmd);
68} 87}
69 88
70int cgit_open_filter(struct cgit_filter *filter, ...) 89static void cleanup_exec_filter(struct cgit_filter *base)
71{
72 int result;
73 va_list ap;
74 va_start(ap, filter);
75 result = filter->open(filter, ap);
76 va_end(ap);
77 return result;
78}
79
80int cgit_close_filter(struct cgit_filter *filter)
81{
82 return filter->close(filter);
83}
84
85void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix)
86{
87 filter->fprintf(filter, f, prefix);
88}
89
90void cgit_exec_filter_init(struct cgit_exec_filter *filter, char *cmd, char **argv)
91{ 90{
92 memset(filter, 0, sizeof(*filter)); 91 struct cgit_exec_filter *filter = (struct cgit_exec_filter *) base;
93 filter->base.open = open_exec_filter; 92 if (filter->argv) {
94 filter->base.close = close_exec_filter; 93 free(filter->argv);
95 filter->base.fprintf = fprintf_exec_filter; 94 filter->argv = NULL;
96 filter->cmd = cmd; 95 }
97 filter->argv = argv; 96 if (filter->cmd) {
97 free(filter->cmd);
98 filter->cmd = NULL;
99 }
98} 100}
99 101
100static struct cgit_filter *new_exec_filter(const char *cmd, filter_type filtertype) 102static struct cgit_filter *new_exec_filter(const char *cmd, filter_type filtertype)
@@ -125,6 +127,39 @@ static struct cgit_filter *new_exec_filter(const char *cmd, filter_type filterty
125 return &f->base; 127 return &f->base;
126} 128}
127 129
130void cgit_exec_filter_init(struct cgit_exec_filter *filter, char *cmd, char **argv)
131{
132 memset(filter, 0, sizeof(*filter));
133 filter->base.open = open_exec_filter;
134 filter->base.close = close_exec_filter;
135 filter->base.fprintf = fprintf_exec_filter;
136 filter->base.cleanup = cleanup_exec_filter;
137 filter->cmd = cmd;
138 filter->argv = argv;
139}
140
141int cgit_open_filter(struct cgit_filter *filter, ...)
142{
143 int result;
144 va_list ap;
145 va_start(ap, filter);
146 result = filter->open(filter, ap);
147 va_end(ap);
148 return result;
149}
150
151int cgit_close_filter(struct cgit_filter *filter)
152{
153 return filter->close(filter);
154}
155
156void cgit_fprintf_filter(struct cgit_filter *filter, FILE *f, const char *prefix)
157{
158 filter->fprintf(filter, f, prefix);
159}
160
161
162
128static const struct { 163static const struct {
129 const char *prefix; 164 const char *prefix;
130 struct cgit_filter *(*ctor)(const char *cmd, filter_type filtertype); 165 struct cgit_filter *(*ctor)(const char *cmd, filter_type filtertype);
@@ -161,3 +196,4 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
161 196
162 die("Invalid filter type: %.*s", (int) len, cmd); 197 die("Invalid filter type: %.*s", (int) len, cmd);
163} 198}
199