diff options
-rw-r--r-- | src/afb-api-so-v1.c | 53 | ||||
-rw-r--r-- | src/afb-api-so-v2.c | 49 | ||||
-rw-r--r-- | src/afb-export.c | 173 | ||||
-rw-r--r-- | src/afb-export.h | 10 |
4 files changed, 128 insertions, 157 deletions
diff --git a/src/afb-api-so-v1.c b/src/afb-api-so-v1.c index ef73b343..b885cf72 100644 --- a/src/afb-api-so-v1.c +++ b/src/afb-api-so-v1.c @@ -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"); diff --git a/src/afb-api-so-v2.c b/src/afb-api-so-v2.c index dcefc769..14a92a9f 100644 --- a/src/afb-api-so-v2.c +++ b/src/afb-api-so-v2.c @@ -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"); 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; +} + diff --git a/src/afb-export.h b/src/afb-export.h index 8016c6fc..853fc5d4 100644 --- a/src/afb-export.h +++ b/src/afb-export.h @@ -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); |