X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;ds=inline;f=src%2Fafb-apis.c;h=6e093550e4113cde18613a80f1f20ff1184c1c38;hb=43d031e1833c5d373600cf44c05d760ade9a150d;hp=de122b6bdf5434e43158c8de83bf835c31cd6101;hpb=0b838a6101edc810098ee0645d3bfd966096ae07;p=src%2Fapp-framework-binder.git diff --git a/src/afb-apis.c b/src/afb-apis.c index de122b6b..6e093550 100644 --- a/src/afb-apis.c +++ b/src/afb-apis.c @@ -27,8 +27,8 @@ #include "verbose.h" #include "afb-apis.h" #include "afb-context.h" -#include "afb-hook.h" #include "afb-xreq.h" +#include "jobs.h" #include @@ -42,6 +42,16 @@ struct api_desc { static struct api_desc *apis_array = NULL; static int apis_count = 0; +static int apis_timeout = 15; + +/** + * Set the API timeout + * @param to the timeout in seconds + */ +void afb_apis_set_timeout(int to) +{ + apis_timeout = to; +} /** * Checks wether 'name' is a valid API name. @@ -195,7 +205,7 @@ int afb_apis_start_service(const char *api, int share_session, int onneed) for (i = 0 ; i < apis_count ; i++) { if (!strcasecmp(apis_array[i].name, api)) - return apis_array[i].api.service_start(apis_array[i].api.closure, share_session, onneed); + return apis_array[i].api.itf->service_start(apis_array[i].api.closure, share_session, onneed); } ERROR("can't find service %s", api); errno = ENOENT; @@ -213,7 +223,7 @@ int afb_apis_start_all_services(int share_session) int i, rc; for (i = 0 ; i < apis_count ; i++) { - rc = apis_array[i].api.service_start(apis_array[i].api.closure, share_session, 1); + rc = apis_array[i].api.itf->service_start(apis_array[i].api.closure, share_session, 1); if (rc < 0) return rc; } @@ -221,27 +231,157 @@ int afb_apis_start_all_services(int share_session) } /** - * Dispatch the request 'req' with the 'context' to the - * method of 'api' and 'verb'. - * @param req the request to dispatch - * @param context the context of the request - * @param api the api of the verb - * @param verb the verb within the api + * Internal direct dispatch of the request 'xreq' + * @param xreq the request to dispatch */ -void afb_apis_call(struct afb_xreq *xreq) +static void do_call_direct(struct afb_xreq *xreq) { const struct api_desc *a; - /* init hooking the request */ - // TODO req = afb_hook_req_call(req, context, api, verb); - /* search the api */ a = search(xreq->api); if (!a) afb_xreq_fail_f(xreq, "unknown-api", "api %s not found", xreq->api); else { xreq->context.api_key = a->api.closure; - a->api.call(a->api.closure, xreq); + a->api.itf->call(a->api.closure, xreq); + } +} + +/** + * Asynchronous dispatch callback for the request 'xreq' + * @param signum 0 on normal flow or the signal number that interupted the normal flow + */ +static void do_call_async(int signum, void *arg) +{ + struct afb_xreq *xreq = arg; + + if (signum != 0) + afb_xreq_fail_f(xreq, "aborted", "signal %s(%d) caught", strsignal(signum), signum); + else { + do_call_direct(xreq); + } + afb_xreq_unref(xreq); +} + +/** + * Dispatch the request 'xreq' synchronously and directly. + * @param xreq the request to dispatch + */ +void afb_apis_call_direct(struct afb_xreq *xreq) +{ + afb_xreq_begin(xreq); + do_call_direct(xreq); +} + +/** + * Dispatch the request 'xreq' asynchronously. + * @param xreq the request to dispatch + */ +void afb_apis_call(struct afb_xreq *xreq) +{ + int rc; + + afb_xreq_begin(xreq); + afb_xreq_addref(xreq); + rc = jobs_queue(NULL, apis_timeout, do_call_async, xreq); + if (rc < 0) { + /* TODO: allows or not to proccess it directly as when no threading? (see above) */ + ERROR("can't process job with threads: %m"); + afb_xreq_fail_f(xreq, "cancelled", "not able to create a job for the task"); + afb_xreq_unref(xreq); + } +} + +/** + * Ask to update the hook flags of the 'api' + * @param api the api to update (NULL updates all) + */ +void afb_apis_update_hooks(const char *api) +{ + const struct api_desc *i, *e; + + if (!api) { + i = apis_array; + e = &apis_array[apis_count]; + } else { + i = search(api); + e = &i[!!i]; + } + while (i != e) { + if (i->api.itf->update_hooks) + i->api.itf->update_hooks(i->api.closure); + i++; + } +} + +/** + * Set the verbosity level of the 'api' + * @param api the api to set (NULL set all) + */ +void afb_apis_set_verbosity(const char *api, int level) +{ + const struct api_desc *i, *e; + + if (!api) { + i = apis_array; + e = &apis_array[apis_count]; + } else { + i = search(api); + e = &i[!!i]; + } + while (i != e) { + if (i->api.itf->set_verbosity) + i->api.itf->set_verbosity(i->api.closure, level); + i++; + } +} + +/** + * Set the verbosity level of the 'api' + * @param api the api to set (NULL set all) + */ +int afb_apis_get_verbosity(const char *api) +{ + const struct api_desc *i; + + i = api ? search(api) : NULL; + if (!i) { + errno = ENOENT; + return -1; + } + if (!i->api.itf->get_verbosity) + return 0; + + return i->api.itf->get_verbosity(i->api.closure); +} + +/** + * Get the list of api names + * @return a NULL terminated array of api names. Must be freed. + */ +const char **afb_apis_get_names() +{ + size_t size; + char *dest; + const char **names; + int i; + + size = apis_count * (1 + sizeof(*names)) + sizeof(*names); + for (i = 0 ; i < apis_count ; i++) + size += strlen(apis_array[i].name); + + names = malloc(size); + if (!names) + errno = ENOMEM; + else { + dest = (void*)&names[apis_count+1]; + for (i = 0 ; i < apis_count ; i++) { + names[i] = dest; + dest = stpcpy(dest, apis_array[i].name) + 1; + } + names[i] = NULL; } + return names; }