aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-08-31 09:30:19 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2017-08-31 09:30:19 +0200
commit11e2d4395056c7bd2a618b4fa7ffdd70af05d14e (patch)
tree12088d06154a0f5f27b77a7eef2c131173964877
parentbfffa28ba0483b49770326c4f567950ea80d0fb6 (diff)
afb-svc: make service existing during its initialisation
The initialisation of services is splitted in two parts: - the creation and allocation of the structure for the service. - the initialisation once the structure is ready and recorded. Change-Id: I05c89fb513869d45e6b8413699fba234f00ce6b1 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/afb-api-so-v1.c16
-rw-r--r--src/afb-api-so-v2.c14
-rw-r--r--src/afb-svc.c120
-rw-r--r--src/afb-svc.h15
4 files changed, 71 insertions, 94 deletions
diff --git a/src/afb-api-so-v1.c b/src/afb-api-so-v1.c
index 7e987c22..3eea4645 100644
--- a/src/afb-api-so-v1.c
+++ b/src/afb-api-so-v1.c
@@ -78,6 +78,7 @@ 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);
@@ -108,13 +109,22 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
}
/* get the event handler if any */
- desc->service = afb_svc_create_v1(desc->binding->v1.prefix, apiset, share_session, init, onevent);
+ desc->service = afb_svc_create(desc->binding->v1.prefix, apiset, share_session, onevent, NULL);
if (desc->service == NULL) {
- /* starting error */
- ERROR("Starting service %s failed", desc->binding->v1.prefix);
+ ERROR("Creation of service %s failed", desc->binding->v1.prefix);
return -1;
}
+ /* Starts the service */
+ rc = afb_svc_start_v1(desc->service, init);
+ if (rc < 0) {
+ /* initialisation error */
+ ERROR("Initialisation of service %s failed (%d): %m", desc->binding->v1.prefix, rc);
+ afb_svc_destroy(desc->service, NULL);
+ desc->service = NULL;
+ return rc;
+ }
+
return 0;
}
diff --git a/src/afb-api-so-v2.c b/src/afb-api-so-v2.c
index bc5ecdf7..038f1ce2 100644
--- a/src/afb-api-so-v2.c
+++ b/src/afb-api-so-v2.c
@@ -103,6 +103,7 @@ static void call_sync_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);
@@ -133,13 +134,24 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
}
/* get the event handler if any */
- desc->service = afb_svc_create_v2(desc->binding->api, apiset, share_session, start, onevent, desc->data);
+ desc->service = afb_svc_create(desc->binding->api, apiset, share_session, onevent, &desc->data->service);
if (desc->service == NULL) {
/* starting error */
ERROR("Starting service %s failed", desc->binding->api);
return -1;
}
+ /* Starts the service */
+ rc = afb_svc_start_v2(desc->service, start);
+ if (rc < 0) {
+ /* initialisation error */
+ ERROR("Initialisation of service %s failed (%d): %m", desc->binding->api, rc);
+ afb_svc_destroy(desc->service, &desc->data->service);
+ desc->service = NULL;
+ return rc;
+ }
+
+
return 0;
}
diff --git a/src/afb-svc.c b/src/afb-svc.c
index 7d9f8dcb..212ecfa3 100644
--- a/src/afb-svc.c
+++ b/src/afb-svc.c
@@ -101,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;
@@ -150,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) {
@@ -184,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);
diff --git a/src/afb-svc.h b/src/afb-svc.h
index fb82e3c4..e23c2867 100644
--- a/src/afb-svc.h
+++ b/src/afb-svc.h
@@ -50,20 +50,17 @@ struct afb_svc
int hookflags;
};
-extern 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));
+extern void afb_svc_destroy(struct afb_svc *svc, struct afb_service *service);
-extern struct afb_svc *afb_svc_create_v2(
+extern struct afb_svc *afb_svc_create(
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);
+ struct afb_service *service);
+
+extern int afb_svc_start_v1(struct afb_svc *svc, int (*start)(struct afb_service));
+extern int afb_svc_start_v2(struct afb_svc *svc, int (*start)());
extern void afb_svc_update_hook(struct afb_svc *svc);