Refactor of starting apis
authorJosé Bollo <jose.bollo@iot.bzh>
Wed, 20 Sep 2017 15:24:14 +0000 (17:24 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Mon, 9 Oct 2017 12:08:32 +0000 (14:08 +0200)
Change-Id: Ib2efcd8747c3537714dfa7058bb0623d6e283c3d
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/afb-api-so-v1.c
src/afb-api-so-v2.c
src/afb-export.c
src/afb-export.h

index ef73b34..b885cf7 100644 (file)
@@ -73,53 +73,8 @@ 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);
-
        struct api_so_v1 *desc = closure;
-
-       /* check state */
-       if (afb_export_is_started(desc->export)) {
-               /* not an error when onneed */
-               if (onneed != 0)
-                       goto done;
-
-               /* already started: it is an error */
-               ERROR("Service %s already started", afb_export_apiname(desc->export));
-               return -1;
-       }
-
-       /* get the initialisation */
-       init = dlsym(desc->handle, afb_api_so_v1_service_init);
-       onevent = dlsym(desc->handle, afb_api_so_v1_service_event);
-
-       /* unshare the session if asked */
-       if (!share_session) {
-               rc = afb_export_unshare_session(desc->export);
-               if (rc < 0) {
-                       ERROR("Can't unshare the session for %s", afb_export_apiname(desc->export));
-                       return -1;
-               }
-       }
-
-       /* set event handling */
-       rc = afb_export_handle_events(desc->export, onevent);
-       if (rc < 0) {
-               ERROR("Can't set event handler for %s", afb_export_apiname(desc->export));
-               return -1;
-       }
-
-       /* Starts the service */
-       rc = afb_export_start_v1(desc->export, init);
-       if (rc < 0) {
-               /* initialisation error */
-               ERROR("Initialisation of service %s failed (%d): %m", afb_export_apiname(desc->export), rc);
-               return rc;
-       }
-
-done:
-       return 0;
+       return afb_export_start(desc->export, share_session, onneed, apiset);
 }
 
 static void update_hooks_cb(void *closure)
@@ -243,6 +198,8 @@ int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *apiset)
 {
        struct api_so_v1 *desc;
        struct afb_binding_v1 *(*register_function) (const struct afb_binding_interface_v1 *interface);
+       int (*init)(struct afb_service service);
+       void (*onevent)(const char *event, struct json_object *object);
        struct afb_api afb_api;
        struct afb_export *export;
 
@@ -253,7 +210,9 @@ int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *apiset)
        INFO("binding [%s] is a valid AFB binding V1", path);
 
        /* allocates the description */
-       export = afb_export_create_v1(path);
+       init = dlsym(handle, afb_api_so_v1_service_init);
+       onevent = dlsym(handle, afb_api_so_v1_service_event);
+       export = afb_export_create_v1(path, init, onevent);
        desc = calloc(1, sizeof *desc);
        if (desc == NULL || export == NULL) {
                ERROR("out of memory");
index dcefc76..14a92a9 100644 (file)
@@ -73,53 +73,8 @@ 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 (*start)();
-       void (*onevent)(const char *event, struct json_object *object);
-
        struct api_so_v2 *desc = closure;
-
-       /* check state */
-       if (afb_export_is_started(desc->export)) {
-               /* not an error when onneed */
-               if (onneed != 0)
-                       goto done;
-
-               /* already started: it is an error */
-               ERROR("Service %s already started", afb_export_apiname(desc->export));
-               return -1;
-       }
-
-       /* get the initialisation */
-       start = desc->binding->init;
-       onevent = desc->binding->onevent;
-
-       /* unshare the session if asked */
-       if (!share_session) {
-               rc = afb_export_unshare_session(desc->export);
-               if (rc < 0) {
-                       ERROR("Can't unshare the session for %s", afb_export_apiname(desc->export));
-                       return -1;
-               }
-       }
-
-       /* set event handling */
-       rc = afb_export_handle_events(desc->export, onevent);
-       if (rc < 0) {
-               ERROR("Can't set event handler for %s", afb_export_apiname(desc->export));
-               return -1;
-       }
-
-       /* Starts the service */
-       rc = afb_export_start_v2(desc->export, start);
-       if (rc < 0) {
-               /* initialisation error */
-               ERROR("Initialisation of service %s failed (%d): %m", afb_export_apiname(desc->export), rc);
-               return rc;
-       }
-
-done:
-       return 0;
+       return afb_export_start(desc->export, share_session, onneed, apiset);
 }
 
 static void update_hooks_cb(void *closure)
@@ -286,7 +241,7 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle
        assert(data);
 
        /* allocates the description */
-       export = afb_export_create_v2(binding->api, data);
+       export = afb_export_create_v2(binding->api, data, binding->init, binding->onevent);
        desc = calloc(1, sizeof *desc);
        if (desc == NULL) {
                ERROR("out of memory");
index 75fb1b1..2f16b37 100644 (file)
@@ -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;
+}
+
index 8016c6f..853fc5d 100644 (file)
@@ -24,8 +24,8 @@ struct afb_service;
 struct afb_binding_data_v2;
 struct afb_binding_interface_v1;
 
-extern struct afb_export *afb_export_create_v1(const char *apiname);
-extern struct afb_export *afb_export_create_v2(const char *apiname, struct afb_binding_data_v2 *data);
+extern struct afb_export *afb_export_create_v1(const char *apiname, int (*init)(struct afb_service), void (*onevent)(const char*, struct json_object*));
+extern 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*));
 extern void afb_export_destroy(struct afb_export *export);
 
 extern const char *afb_export_apiname(const struct afb_export *export);
@@ -36,12 +36,10 @@ extern int afb_export_unshare_session(struct afb_export *export);
 extern void afb_export_set_apiset(struct afb_export *export, struct afb_apiset *apiset);
 extern struct afb_apiset *afb_export_get_apiset(struct afb_export *export);
        
-extern int afb_export_is_started(const struct afb_export *export);
 extern struct afb_binding_v1 *afb_export_register_v1(struct afb_export *export, struct afb_binding_v1 *(*regfun)(const struct afb_binding_interface_v1*));
-extern int afb_export_start_v1(struct afb_export *export, int (*start)(struct afb_service));
-extern int afb_export_start_v2(struct afb_export *export, int (*start)());
+extern int afb_export_handle_events_v12(struct afb_export *export, void (*on_event)(const char *event, struct json_object *object));
 
-extern int afb_export_handle_events(struct afb_export *export, void (*on_event)(const char *event, struct json_object *object));
+extern int afb_export_start(struct afb_export *export, int share_session, int onneed, struct afb_apiset *apiset);
 
 extern int afb_export_verbosity_get(const struct afb_export *export);
 extern void afb_export_verbosity_set(struct afb_export *export, int level);