summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-11-16 13:49:48 -0800
committerVito Caputo <vcaputo@pengaru.com>2020-11-16 13:59:52 -0800
commitafacc269ee1527714bb4f02c155c038c766d9a7f (patch)
treeeaa3e62696a0977a608d6029663ce701198012b5
parent71d53baee273ab397533c2585293457a620a66df (diff)
thunk: add thunk_dispatch_keep() non-freeing variant
In scenarios where a thunk instance must be dispatched multiple times, the automatic free is a problem. This commit moves the free out of the dispatch implementations and into the thunk_dispatch() wrapper. So the behavior of thunk_dispatch() is unchanged. The new thunk_dispatch_keep() is a plain ->dispatch(). This does implicitly turn 'thunk_t *' being a free() able allocation into part of the API, which may be a problem later. But who cares, this is a .h for vendoring, not a .so w/ABI guarantees.
-rw-r--r--thunk.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/thunk.h b/thunk.h
index 8bcc6d7..4a8060e 100644
--- a/thunk.h
+++ b/thunk.h
@@ -459,7 +459,6 @@ struct thunk_t {
assert(env); \
\
r = _THUNK_GEN_DISPATCH(_name, env, __VA_ARGS__); \
- free(env); \
\
return r; \
} \
@@ -538,7 +537,6 @@ struct thunk_t {
assert(env); \
\
r = _THUNK_GEN_DISPATCH(_name, env, __VA_ARGS__); \
- free(env); \
\
return r; \
} \
@@ -664,6 +662,21 @@ struct thunk_t {
* including any payload if THUNK_ALLOC() was used.
*/
static inline int thunk_dispatch(thunk_t *thunk) {
+ int r;
+
+ r = thunk->dispatch(thunk);
+ free(thunk);
+
+ return r;
+}
+
+/* Same as thunk_dispatch() but without the free.
+ * Callers can trivially free thunk instances w/free(), there's
+ * no fancy destructor stuff or anything. So when a thunk needs
+ * to be used repeatedly in a loop for instance, use this, then
+ * just free the thunk yourself.
+ */
+static inline int thunk_dispatch_keep(thunk_t *thunk) {
return thunk->dispatch(thunk);
}
© All Rights Reserved