diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-09-20 15:34:11 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-10-09 14:08:31 +0200 |
commit | 7b42076a77b81e205ecc704c3bb7538716567487 (patch) | |
tree | f1158e4ea14177f01ebf55355aa995257c7b79c8 /include/afb/afb-req-common.h | |
parent | 9ece61d2cbda88878b9f1e6a6e62d3d42cbdef00 (diff) |
Atomic context initialisation for bindings
Change-Id: I3e81b64d57c917da1fba9b3a9387d0f4d7f3e6b7
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'include/afb/afb-req-common.h')
-rw-r--r-- | include/afb/afb-req-common.h | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/include/afb/afb-req-common.h b/include/afb/afb-req-common.h index 1bb017ef..adb0acf4 100644 --- a/include/afb/afb-req-common.h +++ b/include/afb/afb-req-common.h @@ -77,6 +77,8 @@ struct afb_req_itf int (*has_permission)(void *closure, const char *permission); char *(*get_application_id)(void *closure); + + void *(*context_make)(void *closure, int replace, void *(*create_value)(void *creation_closure), void (*free_value)(void*), void *creation_closure); }; /* @@ -257,12 +259,22 @@ static inline void afb_req_context_set(struct afb_req req, void *context, void ( */ static inline void *afb_req_context(struct afb_req req, void *(*create_context)(), void (*free_context)(void*)) { - void *result = afb_req_context_get(req); - if (!result) { - result = create_context(); - afb_req_context_set(req, result, free_context); - } - return result; + return req.itf->context_make(req.closure, 0, (void *(*)(void*))(void*)create_context, free_context, 0); +} + +/* + * Gets the pointer stored by the binding for the session of 'request'. + * If no previous pointer is stored or if 'replace' is not zero, a new value + * is generated using the function 'create_context' called with the 'closure'. + * If 'create_context' is NULL the generated value is 'closure'. + * When a value is created, the function 'free_context' is recorded and will + * be called (with the created value as argument) to free the created value when + * it is not more used. + * This function is atomic: it ensures that 2 threads will not race together. + */ +static inline void *afb_req_context_make(struct afb_req req, int replace, void *(*create_context)(void *closure), void (*free_context)(void*), void *closure) +{ + return req.itf->context_make(req.closure, replace, create_context, free_context, closure); } /* |