aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/afb-api-so-v1.c53
-rw-r--r--src/afb-api-so-v2.c49
-rw-r--r--src/afb-export.c173
-rw-r--r--src/afb-export.h10
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);