X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-svc.c;h=212ecfa3d157406d4318f53370451a7e50a98dfc;hb=6120bbbd2cbd1f06904f887957d92ac740631c55;hp=2a8153e37e1989013104f5e1960f4c2fda943bc0;hpb=052c3aee6362b2e33c060e0fbddd68439bb73dcb;p=src%2Fapp-framework-binder.git diff --git a/src/afb-svc.c b/src/afb-svc.c index 2a8153e3..212ecfa3 100644 --- a/src/afb-svc.c +++ b/src/afb-svc.c @@ -58,6 +58,7 @@ struct svc_req struct jobloop *jobloop; struct json_object *result; int status; + int async; }; /* functions for services */ @@ -100,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; @@ -149,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) { @@ -183,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); @@ -319,9 +278,10 @@ static void svcreq_sync_leave(struct svc_req *svcreq) static void svcreq_reply(struct afb_xreq *xreq, int status, json_object *obj) { struct svc_req *svcreq = CONTAINER_OF_XREQ(struct svc_req, xreq); - if (svcreq->callback) { + if (svcreq->async) { struct afb_svc *svc = svcreq->svc; - svcreq->callback(svcreq->closure, status, obj); + if (svcreq->callback) + svcreq->callback(svcreq->closure, status, obj); HOOK(call_result, svc, status, obj); json_object_put(obj); } else { @@ -362,7 +322,8 @@ static void svc_call(void *closure, const char *api, const char *verb, struct js ERROR("out of memory"); json_object_put(args); ierr = afb_msg_json_internal_error(); - callback(cbclosure, -1, ierr); + if (callback) + callback(cbclosure, -1, ierr); HOOK(call_result, svc, -1, ierr); json_object_put(ierr); return; @@ -372,6 +333,7 @@ static void svc_call(void *closure, const char *api, const char *verb, struct js svcreq->jobloop = NULL; svcreq->callback = callback; svcreq->closure = cbclosure; + svcreq->async = 1; /* terminates and frees ressources if needed */ afb_xreq_process(&svcreq->xreq, svc->apiset); @@ -382,6 +344,7 @@ static int svc_call_sync(void *closure, const char *api, const char *verb, struc { struct afb_svc *svc = closure; struct svc_req *svcreq; + struct json_object *resu; int rc; HOOK(callsync, svc, api, verb, args); @@ -392,7 +355,7 @@ static int svc_call_sync(void *closure, const char *api, const char *verb, struc ERROR("out of memory"); errno = ENOMEM; json_object_put(args); - *result = afb_msg_json_internal_error(); + resu = afb_msg_json_internal_error(); rc = -1; } else { /* initialises the request */ @@ -400,14 +363,19 @@ static int svc_call_sync(void *closure, const char *api, const char *verb, struc svcreq->callback = NULL; svcreq->result = NULL; svcreq->status = 0; + svcreq->async = 0; afb_xreq_addref(&svcreq->xreq); rc = jobs_enter(NULL, 0, svcreq_sync_enter, svcreq); if (rc >= 0) rc = svcreq->status; - *result = (rc >= 0 || svcreq->result) ? svcreq->result : afb_msg_json_internal_error(); + resu = (rc >= 0 || svcreq->result) ? svcreq->result : afb_msg_json_internal_error(); afb_xreq_unref(&svcreq->xreq); } - HOOK(callsync_result, svc, rc, *result); + HOOK(callsync_result, svc, rc, resu); + if (result) + *result = resu; + else + json_object_put(resu); return rc; }