diff options
-rw-r--r-- | src/afb-subcall.c | 185 | ||||
-rw-r--r-- | src/afb-subcall.h | 8 | ||||
-rw-r--r-- | src/afb-xreq.c | 2 |
3 files changed, 70 insertions, 125 deletions
diff --git a/src/afb-subcall.c b/src/afb-subcall.c index 65bef2ff..82128d8a 100644 --- a/src/afb-subcall.c +++ b/src/afb-subcall.c @@ -27,136 +27,60 @@ #include "afb-msg-json.h" #include "afb-apis.h" #include "afb-context.h" +#include "afb-xreq.h" #include "verbose.h" -struct afb_subcall; - -static void subcall_addref(struct afb_subcall *subcall); -static void subcall_unref(struct afb_subcall *subcall); -static struct json_object *subcall_json(struct afb_subcall *subcall); -static struct afb_arg subcall_get(struct afb_subcall *subcall, const char *name); -static void subcall_fail(struct afb_subcall *subcall, const char *status, const char *info); -static void subcall_success(struct afb_subcall *subcall, struct json_object *obj, const char *info); -static const char *subcall_raw(struct afb_subcall *subcall, size_t *size); -static void subcall_send(struct afb_subcall *subcall, const char *buffer, size_t size); -static int subcall_subscribe(struct afb_subcall *subcall, struct afb_event event); -static int subcall_unsubscribe(struct afb_subcall *subcall, struct afb_event event); -static void subcall_session_close(struct afb_subcall *subcall); -static int subcall_session_set_LOA(struct afb_subcall *subcall, unsigned loa); -static void subcall_subcall(struct afb_subcall *subcall, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure); - -const struct afb_req_itf afb_subcall_req_itf = { - .json = (void*)subcall_json, - .get = (void*)subcall_get, - .success = (void*)subcall_success, - .fail = (void*)subcall_fail, - .raw = (void*)subcall_raw, - .send = (void*)subcall_send, - .context_get = (void*)afb_context_get, - .context_set = (void*)afb_context_set, - .addref = (void*)subcall_addref, - .unref = (void*)subcall_unref, - .session_close = (void*)subcall_session_close, - .session_set_LOA = (void*)subcall_session_set_LOA, - .subscribe = (void*)subcall_subscribe, - .unsubscribe = (void*)subcall_unsubscribe, - .subcall = (void*)subcall_subcall +struct subcall; + +static void subcall_destroy(void *closure); +static void subcall_reply(void *closure, int iserror, struct json_object *obj); +static int subcall_subscribe(void *closure, struct afb_event event); +static int subcall_unsubscribe(void *closure, struct afb_event event); + +const struct afb_xreq_query_itf afb_subcall_xreq_itf = { + .reply = subcall_reply, + .unref = subcall_destroy, + .subscribe = subcall_subscribe, + .unsubscribe = subcall_unsubscribe }; -struct afb_subcall +struct subcall { - /* - * CAUTION: 'context' field should be the first because there - * is an implicit convertion to struct afb_context - */ - struct afb_context context; - struct afb_context *original_context; - int refcount; - struct json_object *args; - struct afb_req req; + struct afb_xreq xreq; + struct afb_xreq *caller; void (*callback)(void*, int, struct json_object*); void *closure; }; -static void subcall_addref(struct afb_subcall *subcall) -{ - subcall->refcount++; -} - -static void subcall_unref(struct afb_subcall *subcall) -{ - if (0 == --subcall->refcount) { - json_object_put(subcall->args); - afb_req_unref(subcall->req); - free(subcall); - } -} - -static struct json_object *subcall_json(struct afb_subcall *subcall) -{ - return subcall->args; -} - -static struct afb_arg subcall_get(struct afb_subcall *subcall, const char *name) -{ - return afb_msg_json_get_arg(subcall->args, name); -} - -static void subcall_emit(struct afb_subcall *subcall, int iserror, struct json_object *object) -{ - if (subcall->context.refreshing != 0) - subcall->original_context->refreshing = 1; - - subcall->callback(subcall->closure, iserror, object); - json_object_put(object); -} - -static void subcall_fail(struct afb_subcall *subcall, const char *status, const char *info) -{ - subcall_emit(subcall, 1, afb_msg_json_reply_error(status, info, NULL, NULL)); -} - -static void subcall_success(struct afb_subcall *subcall, struct json_object *obj, const char *info) +static void subcall_destroy(void *closure) { - subcall_emit(subcall, 0, afb_msg_json_reply_ok(info, obj, NULL, NULL)); -} + struct subcall *subcall = closure; -static const char *subcall_raw(struct afb_subcall *subcall, size_t *size) -{ - const char *result = json_object_to_json_string(subcall->args); - if (size != NULL) - *size = strlen(result); - return result; + json_object_put(subcall->xreq.json); + afb_xreq_unref(subcall->caller); + free(subcall); } -static void subcall_send(struct afb_subcall *subcall, const char *buffer, size_t size) +static void subcall_reply(void *closure, int iserror, struct json_object *obj) { - subcall_emit(subcall, 0, json_tokener_parse(buffer)); -} + struct subcall *subcall = closure; -static void subcall_session_close(struct afb_subcall *subcall) -{ - afb_req_session_close(subcall->req); + subcall->callback(subcall->closure, iserror, obj); + json_object_put(obj); } -static int subcall_session_set_LOA(struct afb_subcall *subcall, unsigned loa) +static int subcall_subscribe(void *closure, struct afb_event event) { - return afb_req_session_set_LOA(subcall->req, loa); -} + struct subcall *subcall = closure; -static int subcall_subscribe(struct afb_subcall *subcall, struct afb_event event) -{ - return afb_req_subscribe(subcall->req, event); + return afb_xreq_subscribe(subcall->caller, event); } -static int subcall_unsubscribe(struct afb_subcall *subcall, struct afb_event event) +static int subcall_unsubscribe(void *closure, struct afb_event event) { - return afb_req_unsubscribe(subcall->req, event); -} + struct subcall *subcall = closure; -static void subcall_subcall(struct afb_subcall *subcall, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure) -{ - afb_subcall(&subcall->context, api, verb, args, callback, closure, (struct afb_req){ .itf = &afb_subcall_req_itf, .closure = subcall }); + return afb_xreq_unsubscribe(subcall->caller, event); } void afb_subcall_internal_error(void (*callback)(void*, int, struct json_object*), void *closure) @@ -169,26 +93,49 @@ void afb_subcall_internal_error(void (*callback)(void*, int, struct json_object* callback(closure, 1, obj); } -void afb_subcall(struct afb_context *context, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure, struct afb_req req) +static struct subcall *create_subcall(struct afb_xreq *caller, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure) { - struct afb_subcall *subcall; + struct subcall *subcall; subcall = calloc(1, sizeof *subcall); if (subcall == NULL) { - afb_subcall_internal_error(callback, closure); - return; + return NULL; } - subcall->original_context = context; - subcall->refcount = 1; - subcall->args = args; - subcall->req = req; + + afb_context_subinit(&subcall->xreq.context, &caller->context); + subcall->xreq.refcount = 1; + subcall->xreq.json = args; + subcall->xreq.api = api; /* TODO: alloc ? */ + subcall->xreq.verb = verb; /* TODO: alloc ? */ + subcall->xreq.query = subcall; + subcall->xreq.queryitf = &afb_subcall_xreq_itf; + subcall->caller = caller; subcall->callback = callback; subcall->closure = closure; - subcall->context = *context; - afb_req_addref(req); - afb_apis_call((struct afb_req){ .itf = &afb_subcall_req_itf, .closure = subcall }, &subcall->context, api, verb); - subcall_unref(subcall); + return subcall; +} + +void afb_subcall( + struct afb_xreq *caller, + const char *api, + const char *verb, + struct json_object *args, + void (*callback)(void*, int, struct json_object*), + void *closure +) +{ + struct subcall *subcall; + + subcall = create_subcall(caller, api, verb, args, callback, closure); + if (subcall == NULL) { + afb_subcall_internal_error(callback, closure); + return; + } + + afb_xreq_addref(caller); + afb_apis_xcall(&subcall->xreq); + afb_xreq_unref(&subcall->xreq); } diff --git a/src/afb-subcall.h b/src/afb-subcall.h index e39d8bdd..7d29e1a2 100644 --- a/src/afb-subcall.h +++ b/src/afb-subcall.h @@ -17,18 +17,16 @@ #pragma once -struct afb_context; -struct afb_req; +struct afb_xreq; struct json_object; extern void afb_subcall( - struct afb_context *context, + struct afb_xreq *caller, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), - void *closure, - struct afb_req req); + void *closure); extern void afb_subcall_internal_error( void (*callback)(void*, int, struct json_object*), diff --git a/src/afb-xreq.c b/src/afb-xreq.c index b055f8a9..1a70fe7a 100644 --- a/src/afb-xreq.c +++ b/src/afb-xreq.c @@ -246,7 +246,7 @@ static void xreq_subcall_cb(void *closure, const char *api, const char *verb, st if (xreq->queryitf->subcall) xreq->queryitf->subcall(xreq->query, api, verb, args, callback, cb_closure); else - afb_subcall(&xreq->context, api, verb, args, callback, cb_closure, (struct afb_req){ .itf = &xreq_itf, .closure = xreq }); + afb_subcall(xreq, api, verb, args, callback, cb_closure); } void afb_xreq_success_f(struct afb_xreq *xreq, struct json_object *obj, const char *info, ...) |