summaryrefslogtreecommitdiff
path: root/thunk.h
diff options
context:
space:
mode:
Diffstat (limited to 'thunk.h')
-rw-r--r--thunk.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/thunk.h b/thunk.h
index ef868ab..d2ec683 100644
--- a/thunk.h
+++ b/thunk.h
@@ -418,6 +418,56 @@ struct thunk_t {
\
static int _THUNK_GEN_PROTO(_name, __VA_ARGS__)
+
+/* this is the public variant which is split across declare & define */
+/* put the declaration in the .h, the define in the .c, be sure to include the
+ * .h from the implementing .c - not just the consumers.
+ */
+#define THUNK_DECLARE(_name, ...) \
+ int _THUNK_GEN_PROTO(_name, __VA_ARGS__); \
+ typedef struct __thunk_environment_##_name { \
+ /* struct for encapsulating the calling environment */ \
+ thunk_t __thunk; \
+ _THUNK_GEN_STRUCT (__VA_ARGS__); \
+ } __thunk_environment_##_name; \
+ \
+ int __thunk_dispatch_##_name(thunk_t *thunk); \
+ thunk_t * _THUNK_GEN_PROTO(__thunk_instantiate_##_name, __VA_ARGS__);
+
+
+#define THUNK_DEFINE(_name, ...) \
+ int __thunk_dispatch_##_name(thunk_t *thunk) { \
+ /* dispatch thunk from associated environment */ \
+ __thunk_environment_##_name *env; \
+ int r; \
+ \
+ /* XXX: the embedded __thunk is always at the start, otherwise \
+ * container_of() could be used... */ \
+ env = (__thunk_environment_##_name *)thunk; \
+ assert(env); \
+ \
+ r = _THUNK_GEN_DISPATCH(_name, env, __VA_ARGS__); \
+ free(env); \
+ \
+ return r; \
+ } \
+ \
+ thunk_t * _THUNK_GEN_PROTO(__thunk_instantiate_##_name, __VA_ARGS__) { \
+ /* allocate and populate environment, return it */ \
+ __thunk_environment_##_name *env; \
+ \
+ env = malloc(sizeof(*env)); \
+ assert(env); \
+ \
+ _THUNK_GEN_INITIALIZE(env, __VA_ARGS__); \
+ env->__thunk.dispatch = __thunk_dispatch_##_name; \
+ \
+ return &env->__thunk; \
+ } \
+ \
+ int _THUNK_GEN_PROTO(_name, __VA_ARGS__)
+
+
/* Call the appropriate instantiate function which returns an embedded thunk_t,
* this is how you prepare the thunks established via THUNK_DEFINE(). */
#define _THUNK(_call) \
© All Rights Reserved