X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-apiset.c;h=ae1d9460bfa44ecea0de8a5577978ff94c81722b;hb=ac7a95223a6314cca6250495ea59c3cf7e46e89e;hp=c17881eda2298ede4aab6b145872fa7cc6a87f9f;hpb=3634c468ec7de94f6911c532a606625418fa5133;p=src%2Fapp-framework-binder.git diff --git a/src/afb-apiset.c b/src/afb-apiset.c index c17881ed..ae1d9460 100644 --- a/src/afb-apiset.c +++ b/src/afb-apiset.c @@ -29,16 +29,15 @@ #include "afb-apiset.h" #include "afb-context.h" #include "afb-xreq.h" -#include "jobs.h" - -#include #define INCR 8 /* CAUTION: must be a power of 2 */ /** * Internal description of an api */ -struct api_desc { +struct api_desc +{ + int status; const char *name; /**< name of the api */ struct afb_api api; /**< handler of the api */ }; @@ -50,7 +49,6 @@ struct afb_apiset { struct api_desc *apis; /**< description of apis */ struct afb_apiset *subset; /**< subset if any */ - struct afb_api defapi; /**< default api if any */ int count; /**< count of apis in the set */ int timeout; /**< the timeout in second for the apiset */ int refcount; /**< reference count for freeing resources */ @@ -63,10 +61,10 @@ struct afb_apiset * @param name the api name to search * @return the descriptor if found or NULL otherwise */ -static const struct api_desc *search(struct afb_apiset *set, const char *name) +static struct api_desc *search(struct afb_apiset *set, const char *name) { int i, c, up, lo; - const struct api_desc *a; + struct api_desc *a; /* dichotomic search of the api */ /* initial slice */ @@ -137,7 +135,6 @@ struct afb_apiset *afb_apiset_create(const char *name, int timeout) set->timeout = timeout; set->refcount = 1; set->subset = NULL; - set->defapi.itf = NULL; if (name) strcpy(set->name, name); else @@ -146,6 +143,15 @@ struct afb_apiset *afb_apiset_create(const char *name, int timeout) return set; } +/** + * the name of the apiset + * @param set the api set + * @return the name of the set + */ +const char *afb_apiset_name(struct afb_apiset *set) +{ + return set->name; +} /** * Get the API timeout of the set @@ -194,51 +200,6 @@ void afb_apiset_subset_set(struct afb_apiset *set, struct afb_apiset *subset) afb_apiset_unref(tmp); } -/** - * Check if the apiset has a default api - * @param set the api set - * @return 1 if the set has a default api or 0 otherwise - */ -int afb_apiset_default_api_exist(struct afb_apiset *set) -{ - return !!set->defapi.itf; -} - -/** - * Get the default api of the api set. - * @param set the api set - * @param api where to store the default api - * @return 0 in case of success or -1 when no default api is set - */ -int afb_apiset_default_api_get(struct afb_apiset *set, struct afb_api *api) -{ - if (set->defapi.itf) { - *api = set->defapi; - return 0; - } - errno = ENOENT; - return -1; -} - -/** - * Set the default api of the api set - * @param set the api set - * @param subset the subset to set - */ -void afb_apiset_default_api_set(struct afb_apiset *set, struct afb_api api) -{ - set->defapi = api; -} - -/** - * Set the default api of the api set - * @param set the api set - */ -void afb_apiset_default_api_drop(struct afb_apiset *set) -{ - set->defapi.itf = NULL; -} - /** * Adds the api of 'name' described by 'api'. * @param set the api set @@ -246,7 +207,6 @@ void afb_apiset_default_api_drop(struct afb_apiset *set) * @param api the api * @returns 0 in case of success or -1 in case * of error with errno set: - * - EINVAL if name isn't valid * - EEXIST if name already registered * - ENOMEM when out of memory */ @@ -255,13 +215,6 @@ int afb_apiset_add(struct afb_apiset *set, const char *name, struct afb_api api) struct api_desc *apis; int i, c; - /* Checks the api name */ - if (!afb_api_is_valid_name(name)) { - ERROR("invalid api name forbidden (name is '%s')", name); - errno = EINVAL; - goto error; - } - /* check previously existing plugin */ for (i = 0 ; i < set->count ; i++) { c = strcasecmp(set->apis[i].name, name); @@ -290,11 +243,12 @@ int afb_apiset_add(struct afb_apiset *set, const char *name, struct afb_api api) memmove(apis + 1, apis, ((unsigned)(set->count - i)) * sizeof *apis); /* record the plugin */ + apis->status = -1; apis->api = api; apis->name = name; set->count++; - NOTICE("API %s added", name); + INFO("API %s added", name); return 0; @@ -330,33 +284,93 @@ int afb_apiset_del(struct afb_apiset *set, const char *name) return -1; } +/** + * Get from the 'set' the API of 'name' in 'api' with fallback to subset or default api + * @param set the set of API + * @param name the name of the API to get + * @param rec if not zero look also recursively in subsets + * @return the api pointer in case of success or NULL in case of error + */ +static struct api_desc *lookup(struct afb_apiset *set, const char *name, int rec) +{ + struct api_desc *i = search(set, name); + return i || !rec || !set->subset ? i : lookup(set->subset, name, rec); +} + /** * Get from the 'set' the API of 'name' in 'api' * @param set the set of API * @param name the name of the API to get - * @param api the structure where to store data about the API of name - * @return 0 in case of success or -1 in case of error + * @param rec if not zero look also recursively in subsets + * @return the api pointer in case of success or NULL in case of error */ -int afb_apiset_get(struct afb_apiset *set, const char *name, struct afb_api *api) +const struct afb_api *afb_apiset_lookup(struct afb_apiset *set, const char *name, int rec) { - const struct api_desc *i; + struct api_desc *i; - i = search(set, name); - if (i) { - *api = i->api; - return 0; - } + i = lookup(set, name, rec); + if (i) + return &i->api; + errno = ENOENT; + return NULL; +} - if (set->subset && 0 == afb_apiset_get(set->subset, name, api)) - return 0; +/** + * Starts the service 'api'. + * @param api the api + * @param share_session if true start the servic"e in a shared session + * if false start it in its own session + * @param onneed if true start the service if possible, if false the api + * must be a service + * @return a positive number on success + */ +static int start_api(struct afb_apiset *set, struct api_desc *api, int share_session, int onneed) +{ + int rc; - if (set->defapi.itf) { - *api = set->defapi; + if (api->status == 0) return 0; + else if (api->status > 0) { + errno = api->status; + return -1; } + INFO("API %s starting...", api->name); + if (api->api.itf->service_start) { + api->status = EBUSY; + rc = api->api.itf->service_start(api->api.closure, share_session, onneed, set); + if (rc < 0) { + api->status = errno ?: ECANCELED; + ERROR("The api %s failed to start (%d)", api->name, rc); + return -1; + } + } else if (!onneed) { + /* already started: it is an error */ + ERROR("The api %s is not a startable service", api->name); + api->status = EINVAL; + return -1; + } + NOTICE("API %s started", api->name); + api->status = 0; + return 0; +} + +/** + * Get from the 'set' the API of 'name' in 'api' + * @param set the set of API + * @param name the name of the API to get + * @param rec if not zero look also recursively in subsets + * @return 0 in case of success or -1 in case of error + */ +const struct afb_api *afb_apiset_lookup_started(struct afb_apiset *set, const char *name, int rec) +{ + struct api_desc *i; + + i = lookup(set, name, rec); + if (i) + return i->status && start_api(set, i, 1, 1) ? NULL : &i->api; errno = ENOENT; - return -1; + return NULL; } /** @@ -371,7 +385,7 @@ int afb_apiset_get(struct afb_apiset *set, const char *name, struct afb_api *api */ int afb_apiset_start_service(struct afb_apiset *set, const char *name, int share_session, int onneed) { - const struct api_desc *a; + struct api_desc *a; a = search(set, name); if (!a) { @@ -380,16 +394,7 @@ int afb_apiset_start_service(struct afb_apiset *set, const char *name, int share return -1; } - if (a->api.itf->service_start) - return a->api.itf->service_start(a->api.closure, share_session, onneed, set); - - if (onneed) - return 0; - - /* already started: it is an error */ - ERROR("The api %s is not a startable service", name); - errno = EINVAL; - return -1; + return start_api(set, a, share_session, onneed); } /** @@ -402,19 +407,18 @@ int afb_apiset_start_service(struct afb_apiset *set, const char *name, int share int afb_apiset_start_all_services(struct afb_apiset *set, int share_session) { int rc; - const struct api_desc *i, *e; + struct api_desc *i, *e; i = set->apis; e = &set->apis[set->count]; while (i != e) { - if (i->api.itf->service_start) { - rc = i->api.itf->service_start(i->api.closure, share_session, 1, set); - if (rc < 0) - return rc; - } + rc = start_api(set, i, share_session, 1); + if (rc < 0) + return rc; i++; } - return 0; + + return set->subset ? afb_apiset_start_all_services(set->subset, share_session) : 0; } /** @@ -464,9 +468,10 @@ void afb_apiset_set_verbosity(struct afb_apiset *set, const char *name, int leve } /** - * Set the verbosity level of the 'api' + * Get the verbosity level of the 'api' * @param set the api set - * @param name the api to set (NULL set all) + * @param name the api to get + * @return the verbosity level or -1 in case of error */ int afb_apiset_get_verbosity(struct afb_apiset *set, const char *name) { @@ -477,12 +482,27 @@ int afb_apiset_get_verbosity(struct afb_apiset *set, const char *name) errno = ENOENT; return -1; } + if (!i->api.itf->get_verbosity) - return 0; + return verbosity; return i->api.itf->get_verbosity(i->api.closure); } +/** + * Get the description of the API of 'name' + * @param set the api set + * @param name the api whose description is required + * @return the description or NULL + */ +struct json_object *afb_apiset_describe(struct afb_apiset *set, const char *name) +{ + const struct api_desc *i; + + i = name ? search(set, name) : NULL; + return i && i->api.itf->describe ? i->api.itf->describe(i->api.closure) : NULL; +} + /** * Get the list of api names * @param set the api set @@ -513,3 +533,27 @@ const char **afb_apiset_get_names(struct afb_apiset *set) return names; } +/** + * Enumerate the api names to a callback. + * @param set the api set + * @param callback the function to call for each name + * @param closure the closure for the callback + */ +void afb_apiset_enum(struct afb_apiset *set, int rec, void (*callback)(struct afb_apiset *set, const char *name, void *closure), void *closure) +{ + struct afb_apiset *iset; + struct api_desc *i, *e; + + iset = set; + while (iset) { + i = iset->apis; + e = &i[iset->count]; + while (i != e) { + if (lookup(set, i->name, 1) == i) + callback(iset, i->name, closure); + i++; + } + iset = rec ? iset->subset : NULL; + } +} +