From 91b744a510bbf41526f0931df2320379bec87c38 Mon Sep 17 00:00:00 2001 From: José Bollo Date: Wed, 20 Sep 2017 17:24:14 +0200 Subject: Refactor of starting apis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib2efcd8747c3537714dfa7058bb0623d6e283c3d Signed-off-by: José Bollo --- src/afb-export.c | 173 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 116 insertions(+), 57 deletions(-) (limited to 'src/afb-export.c') diff --git a/src/afb-export.c b/src/afb-export.c index 75fb1b17..2f16b375 100644 --- a/src/afb-export.c +++ b/src/afb-export.c @@ -84,8 +84,16 @@ struct afb_export /* event listener for service or NULL */ struct afb_evt_listener *listener; - /* event callback for service */ - void (*on_event)(const char *event, struct json_object *object); + /* start function */ + union { + int (*v1)(struct afb_service); + int (*v2)(); + } init; + + /* event handling */ + union { + void (*v12)(const char *event, struct json_object *object); + } on_event; /* exported data */ union { @@ -651,22 +659,22 @@ static const struct afb_service_itf hooked_service_itf = { /* * Propagates the event to the service */ -static void export_on_event(void *closure, const char *event, int eventid, struct json_object *object) +static void export_on_event_v12(void *closure, const char *event, int eventid, struct json_object *object) { struct afb_export *export = closure; if (export->hooksvc & afb_hook_flag_svc_on_event_before) afb_hook_svc_on_event_before(export, event, eventid, object); - export->on_event(event, object); + export->on_event.v12(event, object); if (export->hooksvc & afb_hook_flag_svc_on_event_after) afb_hook_svc_on_event_after(export, event, eventid, object); json_object_put(object); } /* the interface for events */ -static const struct afb_evt_itf evt_itf = { - .broadcast = export_on_event, - .push = export_on_event +static const struct afb_evt_itf evt_v12_itf = { + .broadcast = export_on_event_v12, + .push = export_on_event_v12 }; /************************************************************************************************************* @@ -715,10 +723,12 @@ void afb_export_destroy(struct afb_export *export) } } -struct afb_export *afb_export_create_v1(const char *apiname) +struct afb_export *afb_export_create_v1(const char *apiname, int (*init)(struct afb_service), void (*onevent)(const char*, struct json_object*)) { struct afb_export *export = create(apiname, Api_Version_1); if (export) { + export->init.v1 = init; + export->on_event.v12 = onevent; export->export.v1.verbosity = verbosity; export->export.v1.mode = AFB_MODE_LOCAL; export->export.v1.daemon.closure = export; @@ -727,10 +737,12 @@ struct afb_export *afb_export_create_v1(const char *apiname) return export; } -struct afb_export *afb_export_create_v2(const char *apiname, struct afb_binding_data_v2 *data) +struct afb_export *afb_export_create_v2(const char *apiname, struct afb_binding_data_v2 *data, int (*init)(), void (*onevent)(const char*, struct json_object*)) { struct afb_export *export = create(apiname, Api_Version_2); if (export) { + export->init.v2 = init; + export->on_event.v12 = onevent; export->export.v2 = data; data->daemon.closure = export; data->service.closure = export; @@ -801,30 +813,35 @@ struct afb_apiset *afb_export_get_apiset(struct afb_export *export) /* * Creates a new service */ -int afb_export_handle_events(struct afb_export *export, void (*on_event)(const char *event, struct json_object *object)) +int afb_export_handle_events_v12(struct afb_export *export, void (*on_event)(const char *event, struct json_object *object)) { - if (on_event != export->on_event) { - if (!on_event) { + /* check version */ + switch (export->version) { + case Api_Version_1: case Api_Version_2: break; + default: + ERROR("invalid version 12 for API %s", export->apiname); + errno = EINVAL; + return -1; + } + + /* set the event handler */ + if (!on_event) { + if (export->listener) { afb_evt_listener_unref(export->listener); export->listener = NULL; - } else if (!export->listener) { - export->listener = afb_evt_listener_create(&evt_itf, export); + } + export->on_event.v12 = on_event; + } else { + export->on_event.v12 = on_event; + if (!export->listener) { + export->listener = afb_evt_listener_create(&evt_v12_itf, export); if (export->listener == NULL) return -1; } - export->on_event = on_event; } return 0; } - - -int afb_export_is_started(const struct afb_export *export) -{ - return export->state != Api_State_Pre_Init; -} - - /* * Starts a new service (v1) */ @@ -833,40 +850,6 @@ struct afb_binding_v1 *afb_export_register_v1(struct afb_export *export, struct return regfun(&export->export.v1); } -int afb_export_start_v1(struct afb_export *export, int (*start)(struct afb_service)) -{ - int rc; - struct afb_service svc = { .itf = &hooked_service_itf, .closure = export }; - - if (export->hooksvc & afb_hook_flag_svc_start_before) - afb_hook_svc_start_before(export); - export->state = Api_State_Init; - rc = start ? start(svc) : 0; - export->state = Api_State_Run; - if (export->hooksvc & afb_hook_flag_svc_start_after) - afb_hook_svc_start_after(export, rc); - return rc; -} - -/* - * Starts a new service (v2) - */ -int afb_export_start_v2(struct afb_export *export, int (*start)()) -{ - int rc; - - if (export->hooksvc & afb_hook_flag_svc_start_before) - afb_hook_svc_start_before(export); - export->state = Api_State_Init; - rc = start ? start() : 0; - export->state = Api_State_Run; - if (export->hooksvc & afb_hook_flag_svc_start_after) - afb_hook_svc_start_after(export, rc); - if (rc >= 0) - export->state = Api_State_Run; - return rc; -} - int afb_export_verbosity_get(const struct afb_export *export) { switch (export->version) { @@ -884,3 +867,79 @@ void afb_export_verbosity_set(struct afb_export *export, int level) } } +/************************************************************************************************************* + ************************************************************************************************************* + ************************************************************************************************************* + ************************************************************************************************************* + N E W + ************************************************************************************************************* + ************************************************************************************************************* + ************************************************************************************************************* + *************************************************************************************************************/ + +int afb_export_start(struct afb_export *export, int share_session, int onneed, struct afb_apiset *apiset) +{ + int rc; + + /* check state */ + if (export->state != Api_State_Pre_Init) { + /* not an error when onneed */ + if (onneed != 0) + goto done; + + /* already started: it is an error */ + ERROR("Service of API %s already started", export->apiname); + return -1; + } + + /* unshare the session if asked */ + if (!share_session) { + rc = afb_export_unshare_session(export); + if (rc < 0) { + ERROR("Can't unshare the session for %s", export->apiname); + return -1; + } + } + + /* set event handling */ + switch (export->version) { + case Api_Version_1: + case Api_Version_2: + rc = afb_export_handle_events_v12(export, export->on_event.v12); + break; + default: + rc = 0; + break; + } + if (rc < 0) { + ERROR("Can't set event handler for %s", export->apiname); + return -1; + } + + /* Starts the service */ + if (export->hooksvc & afb_hook_flag_svc_start_before) + afb_hook_svc_start_before(export); + export->state = Api_State_Init; + switch (export->version) { + case Api_Version_1: + rc = export->init.v1 ? export->init.v1((struct afb_service){ .itf = &hooked_service_itf, .closure = export }) : 0; + break; + case Api_Version_2: + rc = export->init.v2 ? export->init.v2() : 0; + break; + default: + break; + } + export->state = Api_State_Run; + if (export->hooksvc & afb_hook_flag_svc_start_after) + afb_hook_svc_start_after(export, rc); + if (rc < 0) { + /* initialisation error */ + ERROR("Initialisation of service API %s failed (%d): %m", export->apiname, rc); + return rc; + } + +done: + return 0; +} + -- cgit 1.2.3-korg