From 11e2d4395056c7bd2a618b4fa7ffdd70af05d14e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Thu, 31 Aug 2017 09:30:19 +0200 Subject: [PATCH] afb-svc: make service existing during its initialisation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The initialisation of services is splitted in two parts: - the creation and allocation of the structure for the service. - the initialisation once the structure is ready and recorded. Change-Id: I05c89fb513869d45e6b8413699fba234f00ce6b1 Signed-off-by: José Bollo --- src/afb-api-so-v1.c | 16 +++++-- src/afb-api-so-v2.c | 14 +++++- src/afb-svc.c | 120 +++++++++++++++++----------------------------------- src/afb-svc.h | 15 +++---- 4 files changed, 71 insertions(+), 94 deletions(-) diff --git a/src/afb-api-so-v1.c b/src/afb-api-so-v1.c index 7e987c22..3eea4645 100644 --- a/src/afb-api-so-v1.c +++ b/src/afb-api-so-v1.c @@ -78,6 +78,7 @@ static void call_cb(void *closure, struct afb_xreq *xreq) static int service_start_cb(void *closure, int share_session, int onneed, struct afb_apiset *apiset) { + int rc; int (*init)(struct afb_service service); void (*onevent)(const char *event, struct json_object *object); @@ -108,13 +109,22 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct } /* get the event handler if any */ - desc->service = afb_svc_create_v1(desc->binding->v1.prefix, apiset, share_session, init, onevent); + desc->service = afb_svc_create(desc->binding->v1.prefix, apiset, share_session, onevent, NULL); if (desc->service == NULL) { - /* starting error */ - ERROR("Starting service %s failed", desc->binding->v1.prefix); + ERROR("Creation of service %s failed", desc->binding->v1.prefix); return -1; } + /* Starts the service */ + rc = afb_svc_start_v1(desc->service, init); + if (rc < 0) { + /* initialisation error */ + ERROR("Initialisation of service %s failed (%d): %m", desc->binding->v1.prefix, rc); + afb_svc_destroy(desc->service, NULL); + desc->service = NULL; + return rc; + } + return 0; } diff --git a/src/afb-api-so-v2.c b/src/afb-api-so-v2.c index bc5ecdf7..038f1ce2 100644 --- a/src/afb-api-so-v2.c +++ b/src/afb-api-so-v2.c @@ -103,6 +103,7 @@ static void call_sync_cb(void *closure, struct afb_xreq *xreq) static int service_start_cb(void *closure, int share_session, int onneed, struct afb_apiset *apiset) { + int rc; int (*start)(); void (*onevent)(const char *event, struct json_object *object); @@ -133,13 +134,24 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct } /* get the event handler if any */ - desc->service = afb_svc_create_v2(desc->binding->api, apiset, share_session, start, onevent, desc->data); + desc->service = afb_svc_create(desc->binding->api, apiset, share_session, onevent, &desc->data->service); if (desc->service == NULL) { /* starting error */ ERROR("Starting service %s failed", desc->binding->api); return -1; } + /* Starts the service */ + rc = afb_svc_start_v2(desc->service, start); + if (rc < 0) { + /* initialisation error */ + ERROR("Initialisation of service %s failed (%d): %m", desc->binding->api, rc); + afb_svc_destroy(desc->service, &desc->data->service); + desc->service = NULL; + return rc; + } + + return 0; } diff --git a/src/afb-svc.c b/src/afb-svc.c index 7d9f8dcb..212ecfa3 100644 --- a/src/afb-svc.c +++ b/src/afb-svc.c @@ -101,23 +101,29 @@ static inline struct afb_service to_afb_service(struct afb_svc *svc) /* * Frees a service */ -static void svc_free(struct afb_svc *svc) +void afb_svc_destroy(struct afb_svc *svc, struct afb_service *service) { - if (svc->listener != NULL) - afb_evt_listener_unref(svc->listener); - if (svc->session) - afb_session_unref(svc->session); - afb_apiset_unref(svc->apiset); - free(svc); + if (service) + *service = (struct afb_service){ .itf = NULL, .closure = NULL }; + if (svc) { + if (svc->listener != NULL) + afb_evt_listener_unref(svc->listener); + if (svc->session) + afb_session_unref(svc->session); + afb_apiset_unref(svc->apiset); + free(svc); + } } /* - * Allocates a new service + * Creates a new service */ -static struct afb_svc *afb_svc_alloc( +struct afb_svc *afb_svc_create( const char *api, struct afb_apiset *apiset, - int share_session + int share_session, + void (*on_event)(const char *event, struct json_object *object), + struct afb_service *service ) { struct afb_svc *svc; @@ -150,31 +156,8 @@ static struct afb_svc *afb_svc_alloc( } svc->hookflags = afb_hook_flags_svc(svc->api); - return svc; - -error: - svc_free(svc); - return NULL; -} - -/* - * Creates a new service - */ -struct afb_svc *afb_svc_create_v1( - const char *api, - struct afb_apiset *apiset, - int share_session, - int (*start)(struct afb_service service), - void (*on_event)(const char *event, struct json_object *object) -) -{ - int rc; - struct afb_svc *svc; - - /* allocates the svc handler */ - svc = afb_svc_alloc(api, apiset, share_session); - if (svc == NULL) - goto error; + if (service) + *service = to_afb_service(svc); /* initialises the listener if needed */ if (on_event) { @@ -184,67 +167,42 @@ struct afb_svc *afb_svc_create_v1( goto error; } - /* initialises the svc now */ - if (start) { - HOOK(start_before, svc); - rc = start(to_afb_service(svc)); - HOOK(start_after, svc, rc); - if (rc < 0) - goto error; - } - return svc; error: - svc_free(svc); + afb_svc_destroy(svc, service); return NULL; } /* - * Creates a new service + * Starts a new service (v1) */ -struct afb_svc *afb_svc_create_v2( - const char *api, - struct afb_apiset *apiset, - int share_session, - int (*start)(), - void (*on_event)(const char *event, struct json_object *object), - struct afb_binding_data_v2 *data -) +int afb_svc_start_v1(struct afb_svc *svc, int (*start)(struct afb_service)) { int rc; - struct afb_svc *svc; - - /* allocates the svc handler */ - svc = afb_svc_alloc(api, apiset, share_session); - if (svc == NULL) - goto error; - data->service = to_afb_service(svc); - - /* initialises the listener if needed */ - if (on_event) { - svc->on_event = on_event; - svc->listener = afb_evt_listener_create(&evt_itf, svc); - if (svc->listener == NULL) - goto error; - } - /* starts the svc if needed */ - if (start) { - HOOK(start_before, svc); - rc = start(); - HOOK(start_after, svc, rc); - if (rc < 0) - goto error; - } + HOOK(start_before, svc); + rc = start(to_afb_service(svc)); + HOOK(start_after, svc, rc); + return rc; +} - return svc; +/* + * Starts a new service (v2) + */ +int afb_svc_start_v2(struct afb_svc *svc, int (*start)()) +{ + int rc; -error: - svc_free(svc); - return NULL; + HOOK(start_before, svc); + rc = start(); + HOOK(start_after, svc, rc); + return rc; } +/* + * Request to updates the hooks + */ void afb_svc_update_hook(struct afb_svc *svc) { svc->hookflags = afb_hook_flags_svc(svc->api); diff --git a/src/afb-svc.h b/src/afb-svc.h index fb82e3c4..e23c2867 100644 --- a/src/afb-svc.h +++ b/src/afb-svc.h @@ -50,20 +50,17 @@ struct afb_svc int hookflags; }; -extern struct afb_svc *afb_svc_create_v1( - const char *api, - struct afb_apiset *apiset, - int share_session, - int (*start)(struct afb_service service), - void (*on_event)(const char *event, struct json_object *object)); +extern void afb_svc_destroy(struct afb_svc *svc, struct afb_service *service); -extern struct afb_svc *afb_svc_create_v2( +extern struct afb_svc *afb_svc_create( const char *api, struct afb_apiset *apiset, int share_session, - int (*start)(), void (*on_event)(const char *event, struct json_object *object), - struct afb_binding_data_v2 *data); + struct afb_service *service); + +extern int afb_svc_start_v1(struct afb_svc *svc, int (*start)(struct afb_service)); +extern int afb_svc_start_v2(struct afb_svc *svc, int (*start)()); extern void afb_svc_update_hook(struct afb_svc *svc); -- 2.16.6