From: José Bollo Date: Wed, 24 May 2017 14:56:26 +0000 (+0200) Subject: Handles subcall sync within xreq X-Git-Tag: dab_3.99.2~54 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=commitdiff_plain;h=a86967decc0ff9b139f412fffccc7914e27a80a9;p=src%2Fapp-framework-binder.git Handles subcall sync within xreq Change-Id: Ieac7c589ddadfb67761332443a3fd92038b6d548 Signed-off-by: José Bollo --- diff --git a/src/afb-subcall.c b/src/afb-subcall.c index 8a8c77a9..ef114077 100644 --- a/src/afb-subcall.c +++ b/src/afb-subcall.c @@ -30,21 +30,6 @@ #include "afb-xreq.h" #include "afb-cred.h" #include "verbose.h" -#include "jobs.h" - -struct subcall; - -static void subcall_destroy(struct afb_xreq *xreq); -static void subcall_reply(struct afb_xreq *xreq, int iserror, struct json_object *obj); -static int subcall_subscribe(struct afb_xreq *xreq, struct afb_event event); -static int subcall_unsubscribe(struct afb_xreq *xreq, 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 subcall { @@ -86,35 +71,12 @@ static int subcall_unsubscribe(struct afb_xreq *xreq, struct afb_event event) return afb_xreq_unsubscribe(subcall->caller, event); } -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 subcall *subcall; - size_t lenapi, lenverb; - char *copy; - - lenapi = 1 + strlen(api); - lenverb = 1 + strlen(verb); - subcall = malloc(lenapi + lenverb + sizeof *subcall); - if (subcall == NULL) { - return NULL; - } - afb_xreq_init(&subcall->xreq, &afb_subcall_xreq_itf); - afb_context_subinit(&subcall->xreq.context, &caller->context); - subcall->xreq.cred = afb_cred_addref(caller->cred); - subcall->xreq.json = args; - copy = (char*)&subcall[1]; - memcpy(copy, api, lenapi); - subcall->xreq.api = copy; - copy = ©[lenapi]; - memcpy(copy, verb, lenverb); - subcall->xreq.verb = copy; - subcall->caller = caller; - subcall->callback = callback; - subcall->closure = closure; - afb_xreq_addref(caller); - json_object_get(args); - return subcall; -} +const struct afb_xreq_query_itf afb_subcall_xreq_itf = { + .reply = subcall_reply, + .unref = subcall_destroy, + .subscribe = subcall_subscribe, + .unsubscribe = subcall_unsubscribe +}; void afb_subcall( struct afb_xreq *caller, @@ -126,86 +88,31 @@ void afb_subcall( ) { struct subcall *subcall; + size_t lenapi, lenverb; + char *copy; - subcall = create_subcall(caller, api, verb, args, callback, closure); - if (subcall == NULL) { + lenapi = 1 + strlen(api); + lenverb = 1 + strlen(verb); + subcall = malloc(lenapi + lenverb + sizeof *subcall); + if (subcall == NULL) callback(closure, 1, afb_msg_json_internal_error()); - return; - } - - afb_xreq_process(&subcall->xreq, caller->apiset); -} - -struct subcall_sync -{ - struct afb_xreq *caller; - const char *api; - const char *verb; - struct json_object *args; - struct jobloop *jobloop; - struct json_object *result; - int iserror; -}; - -static void subcall_sync_leave(struct subcall_sync *sync) -{ - struct jobloop *jobloop = sync->jobloop; - sync->jobloop = NULL; - if (jobloop) - jobs_leave(jobloop); -} - -static void subcall_sync_reply(void *closure, int iserror, struct json_object *obj) -{ - struct subcall_sync *sync = closure; - - sync->iserror = iserror; - sync->result = obj; - json_object_get(obj); - subcall_sync_leave(sync); -} - -static void subcall_sync_enter(int signum, void *closure, struct jobloop *jobloop) -{ - struct subcall_sync *sync = closure; - - if (!signum) { - sync->jobloop = jobloop; - afb_xreq_unhooked_subcall(sync->caller, sync->api, sync->verb, sync->args, subcall_sync_reply, sync); - } else { - sync->result = json_object_get(afb_msg_json_internal_error()); - sync->iserror = 1; - subcall_sync_leave(sync); - } -} - -int afb_subcall_sync( - struct afb_xreq *caller, - const char *api, - const char *verb, - struct json_object *args, - struct json_object **result -) -{ - int rc; - struct subcall_sync sync; - - sync.caller = caller; - sync.api = api; - sync.verb = verb; - sync.args = args; - sync.jobloop = NULL; - sync.result = NULL; - sync.iserror = 1; - - rc = jobs_enter(NULL, 0, subcall_sync_enter, &sync); - if (rc < 0) { - sync.result = json_object_get(afb_msg_json_internal_error()); - sync.iserror = 1; + else { + afb_xreq_init(&subcall->xreq, &afb_subcall_xreq_itf); + afb_context_subinit(&subcall->xreq.context, &caller->context); + subcall->xreq.cred = afb_cred_addref(caller->cred); + subcall->xreq.json = args; + copy = (char*)&subcall[1]; + memcpy(copy, api, lenapi); + subcall->xreq.api = copy; + copy = ©[lenapi]; + memcpy(copy, verb, lenverb); + subcall->xreq.verb = copy; + subcall->caller = caller; + subcall->callback = callback; + subcall->closure = closure; + afb_xreq_addref(caller); + json_object_get(args); /* keep args existing */ + afb_xreq_process(&subcall->xreq, caller->apiset); } - rc = !sync.iserror; - *result = sync.result; - return rc; } - diff --git a/src/afb-subcall.h b/src/afb-subcall.h index bf3d8cd1..082b02c8 100644 --- a/src/afb-subcall.h +++ b/src/afb-subcall.h @@ -28,10 +28,3 @@ extern void afb_subcall( void (*callback)(void*, int, struct json_object*), void *closure); -extern int afb_subcall_sync( - struct afb_xreq *caller, - const char *api, - const char *verb, - struct json_object *args, - struct json_object **result); - diff --git a/src/afb-xreq.c b/src/afb-xreq.c index 0ecf62d2..4c5becca 100644 --- a/src/afb-xreq.c +++ b/src/afb-xreq.c @@ -37,6 +37,7 @@ #include "jobs.h" #include "verbose.h" +/******************************************************************************/ static struct json_object *xreq_json_cb(void *closure) { @@ -184,12 +185,73 @@ static void xreq_subcall_cb(void *closure, const char *api, const char *verb, st afb_subcall(xreq, api, verb, args, callback, cb_closure); } +struct xreq_sync +{ + struct afb_xreq *caller; + const char *api; + const char *verb; + struct json_object *args; + struct jobloop *jobloop; + struct json_object *result; + int iserror; +}; + +static void xreq_sync_leave(struct xreq_sync *sync) +{ + struct jobloop *jobloop = sync->jobloop; + if (jobloop) { + sync->jobloop = NULL; + jobs_leave(jobloop); + } +} + +static void xreq_sync_reply(void *closure, int iserror, struct json_object *obj) +{ + struct xreq_sync *sync = closure; + + sync->iserror = iserror; + sync->result = json_object_get(obj); + xreq_sync_leave(sync); +} + +static void xreq_sync_enter(int signum, void *closure, struct jobloop *jobloop) +{ + struct xreq_sync *sync = closure; + + if (!signum) { + sync->jobloop = jobloop; + xreq_subcall_cb(sync->caller, sync->api, sync->verb, sync->args, xreq_sync_reply, sync); + } else { + sync->iserror = 1; + xreq_sync_leave(sync); + } +} + static int xreq_subcallsync_cb(void *closure, const char *api, const char *verb, struct json_object *args, struct json_object **result) { + int rc; + struct xreq_sync sync; struct afb_xreq *xreq = closure; - return afb_subcall_sync(xreq, api, verb, args, result); + + sync.caller = xreq; + sync.api = api; + sync.verb = verb; + sync.args = args; + sync.jobloop = NULL; + sync.result = NULL; + sync.iserror = 1; + + rc = jobs_enter(NULL, 0, xreq_sync_enter, &sync); + if (rc < 0 || sync.iserror) { + *result = sync.result ? : afb_msg_json_internal_error(); + return 0; + } + *result = sync.result; + return 1; } +/******************************************************************************/ + static struct json_object *xreq_hooked_json_cb(void *closure) { struct json_object *r = xreq_json_cb(closure); @@ -333,6 +395,8 @@ static int xreq_hooked_subcallsync_cb(void *closure, const char *api, const char return afb_hook_xreq_subcallsync_result(xreq, r, *result); } +/******************************************************************************/ + const struct afb_req_itf xreq_itf = { .json = xreq_json_cb, .get = xreq_get_cb, @@ -376,6 +440,8 @@ static inline struct afb_req to_req(struct afb_xreq *xreq) return (struct afb_req){ .itf = xreq->hookflags ? &xreq_hooked_itf : &xreq_itf, .closure = xreq }; } +/******************************************************************************/ + struct json_object *afb_xreq_json(struct afb_xreq *xreq) { return afb_req_json(to_req(xreq)); @@ -440,6 +506,16 @@ void afb_xreq_subcall(struct afb_xreq *xreq, const char *api, const char *verb, afb_req_subcall(to_req(xreq), api, verb, args, callback, cb_closure); } +int afb_xreq_unhooked_subcall_sync(struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args, struct json_object **result) +{ + return xreq_subcallsync_cb(xreq, api, verb, args, result); +} + +int afb_xreq_subcall_sync(struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args, struct json_object **result) +{ + return afb_req_subcall_sync(to_req(xreq), api, verb, args, result); +} + static int xreq_session_check_apply_v1(struct afb_xreq *xreq, int sessionflags) { int loa; @@ -553,26 +629,32 @@ void afb_xreq_fail_unknown_verb(struct afb_xreq *xreq) afb_xreq_fail_f(xreq, "unknown-verb", "verb %s unknown within api %s", xreq->verb, xreq->api); } +static void process_sync(struct afb_xreq *xreq) +{ + struct afb_api api; + + /* init hooking */ + afb_hook_init_xreq(xreq); + if (xreq->hookflags) + afb_hook_xreq_begin(xreq); + + /* search the api */ + if (afb_apiset_get(xreq->apiset, xreq->api, &api) < 0) { + afb_xreq_fail_f(xreq, "unknown-api", "api %s not found", xreq->api); + } else { + xreq->context.api_key = api.closure; + api.itf->call(api.closure, xreq); + } +} + static void process_async(int signum, void *arg) { struct afb_xreq *xreq = arg; - struct afb_api api; if (signum != 0) { afb_xreq_fail_f(xreq, "aborted", "signal %s(%d) caught", strsignal(signum), signum); } else { - /* init hooking */ - afb_hook_init_xreq(xreq); - if (xreq->hookflags) - afb_hook_xreq_begin(xreq); - - /* search the api */ - if (afb_apiset_get(xreq->apiset, xreq->api, &api) < 0) { - afb_xreq_fail_f(xreq, "unknown-api", "api %s not found", xreq->api); - } else { - xreq->context.api_key = api.closure; - api.itf->call(api.closure, xreq); - } + process_sync(xreq); } afb_xreq_unref(xreq); } diff --git a/src/afb-xreq.h b/src/afb-xreq.h index fc3e2253..a37b6bfd 100644 --- a/src/afb-xreq.h +++ b/src/afb-xreq.h @@ -118,6 +118,19 @@ extern void afb_xreq_unhooked_subcall( void (*callback)(void*, int, struct json_object*), void *cb_closure); +extern int afb_xreq_unhooked_subcall_sync( + struct afb_xreq *xreq, + const char *api, + const char *verb, + struct json_object *args, + struct json_object **result); +extern int afb_xreq_subcall_sync( + struct afb_xreq *xreq, + const char *api, + const char *verb, + struct json_object *args, + struct json_object **result); + /* initialisation and processing of xreq */ extern void afb_xreq_init(struct afb_xreq *xreq, const struct afb_xreq_query_itf *queryitf);