afb-ditf: track daemon state
authorJosé Bollo <jose.bollo@iot.bzh>
Mon, 4 Sep 2017 11:44:59 +0000 (13:44 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 7 Sep 2017 07:43:13 +0000 (09:43 +0200)
Change-Id: Ic21c79dcd9908919a1a8d13e8747ef0bd2490477
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
docs/afb-binding-references.md
include/afb/afb-daemon-v1.h
include/afb/afb-daemon-v2.h
src/afb-api-so-v1.c
src/afb-api-so-v2.c
src/afb-ditf.c
src/afb-ditf.h

index e340d6b..c266c2e 100644 (file)
@@ -142,6 +142,8 @@ Broadcasting an event send it to any possible listener.
  * Thus, in the case where 'object' should remain available after
  * the function returns, the function 'json_object_get' shall be used.
  *
+ * Calling this function is only forbidden during preinit.
+ *
  * Returns the count of clients that received the event.
  */
 int afb_daemon_broadcast_event(const char *name, struct json_object *object);
@@ -149,6 +151,8 @@ int afb_daemon_broadcast_event(const char *name, struct json_object *object);
 /*
  * Creates an event of 'name' and returns it.
  *
+ * Calling this function is only forbidden during preinit.
+ *
  * See afb_event_is_valid to check if there is an error.
  */
 struct afb_event afb_daemon_make_event(const char *name);
@@ -228,6 +232,7 @@ bindings at its initialization.
 /*
  * Tells that it requires the API of "name" to exist
  * and if 'initialized' is not null to be initialized.
+ * Calling this function is only allowed within init.
  * Returns 0 in case of success or -1 in case of error.
  */
 int afb_daemon_require_api(const char *name, int initialized)
index 8f5ed2f..81cdb12 100644 (file)
@@ -55,6 +55,8 @@ static inline struct sd_bus *afb_daemon_get_system_bus_v1(struct afb_daemon daem
  * Thus, in the case where 'object' should remain available after
  * the function returns, the function 'json_object_get' shall be used.
  *
+ * Calling this function is only forbidden during preinit.
+ *
  * Returns the count of clients that received the event.
  */
 static inline int afb_daemon_broadcast_event_v1(struct afb_daemon daemon, const char *name, struct json_object *object)
@@ -65,6 +67,10 @@ static inline int afb_daemon_broadcast_event_v1(struct afb_daemon daemon, const
 /*
  * Creates an event of 'name' and returns it.
  * 'daemon' MUST be the daemon given in interface when activating the binding.
+ *
+ * Calling this function is only forbidden during preinit.
+ *
+ * See afb_event_is_valid to check if there is an error.
  */
 static inline struct afb_event afb_daemon_make_event_v1(struct afb_daemon daemon, const char *name)
 {
@@ -167,6 +173,7 @@ static inline int afb_daemon_queue_job_v1(struct afb_daemon daemon, void (*callb
 /*
  * Tells that it requires the API of "name" to exist
  * and if 'initialized' is not null to be initialized.
+ * Calling this function is only allowed within init.
  * Returns 0 in case of success or -1 in case of error.
  */
 static inline int afb_daemon_require_api_v1(struct afb_daemon daemon, const char *name, int initialized)
index 481d3de..7ef085b 100644 (file)
@@ -51,6 +51,8 @@ static inline struct sd_bus *afb_daemon_get_system_bus_v2()
  * Thus, in the case where 'object' should remain available after
  * the function returns, the function 'json_object_get' shall be used.
  *
+ * Calling this function is only forbidden during preinit.
+ *
  * Returns the count of clients that received the event.
  */
 static inline int afb_daemon_broadcast_event_v2(const char *name, struct json_object *object)
@@ -60,6 +62,10 @@ static inline int afb_daemon_broadcast_event_v2(const char *name, struct json_ob
 
 /*
  * Creates an event of 'name' and returns it.
+ *
+ * Calling this function is only forbidden during preinit.
+ *
+ * See afb_event_is_valid to check if there is an error.
  */
 static inline struct afb_event afb_daemon_make_event_v2(const char *name)
 {
@@ -144,6 +150,7 @@ static inline struct afb_req afb_daemon_unstore_req_v2(struct afb_stored_req *sr
 /*
  * Tells that it requires the API of "name" to exist
  * and if 'initialized' is not null to be initialized.
+ * Calling this function is only allowed within init.
  * Returns 0 in case of success or -1 in case of error.
  */
 static inline int afb_daemon_require_api_v2(const char *name, int initialized)
index 2a5dc08..a341dac 100644 (file)
@@ -88,7 +88,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
        if (desc->service != NULL) {
                /* not an error when onneed */
                if (onneed != 0)
-                       return 0;
+                       goto done;
 
                /* already started: it is an error */
                ERROR("Service %s already started", desc->binding->v1.prefix);
@@ -101,7 +101,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
        if (init == NULL && onevent == NULL) {
                /* not an error when onneed */
                if (onneed != 0)
-                       return 0;
+                       goto done;
 
                /* no initialisation method */
                ERROR("Binding %s is not a service", desc->binding->v1.prefix);
@@ -116,6 +116,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
        }
 
        /* Starts the service */
+       desc->ditf.state = Daemon_Init;
        rc = afb_svc_start_v1(desc->service, init);
        if (rc < 0) {
                /* initialisation error */
@@ -125,6 +126,8 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
                return rc;
        }
 
+done:
+       desc->ditf.state = Daemon_Run;
        return 0;
 }
 
index 871be52..49fac6b 100644 (file)
@@ -88,7 +88,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
        if (desc->service != NULL) {
                /* not an error when onneed */
                if (onneed != 0)
-                       return 0;
+                       goto done;
 
                /* already started: it is an error */
                ERROR("Service %s already started", desc->binding->api);
@@ -101,7 +101,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
        if (start == NULL && onevent == NULL) {
                /* not an error when onneed */
                if (onneed != 0)
-                       return 0;
+                       goto done;
 
                /* no initialisation method */
                ERROR("Binding %s is not a service", desc->binding->api);
@@ -117,6 +117,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
        }
 
        /* Starts the service */
+       desc->ditf.state = Daemon_Init;
        rc = afb_svc_start_v2(desc->service, start);
        if (rc < 0) {
                /* initialisation error */
@@ -126,7 +127,8 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
                return rc;
        }
 
-
+done:
+       desc->ditf.state = Daemon_Run;
        return 0;
 }
 
index 3fc09e9..28cd46a 100644 (file)
@@ -65,6 +65,14 @@ static struct afb_event event_make_cb(void *closure, const char *name)
        char *event;
        struct afb_ditf *ditf = closure;
 
+       /* check daemon state */
+       if (ditf->state == Daemon_Pre_Init) {
+               
+               ERROR("[API %s] Bad call to 'afb_daemon_event_make(%s)', must not be in PreInit", ditf->api, name);
+               errno = EINVAL;
+               return (struct afb_event){ .itf = NULL, .closure = NULL };
+       }
+
        /* makes the event name */
        plen = strlen(ditf->api);
        nlen = strlen(name);
@@ -83,6 +91,14 @@ static int event_broadcast_cb(void *closure, const char *name, struct json_objec
        char *event;
        struct afb_ditf *ditf = closure;
 
+       /* check daemon state */
+       if (ditf->state == Daemon_Pre_Init) {
+               
+               ERROR("[API %s] Bad call to 'afb_daemon_event_broadcast(%s, %s)', must not be in PreInit", ditf->api, name, json_object_to_json_string(object));
+               errno = EINVAL;
+               return 0;
+       }
+
        /* makes the event name */
        plen = strlen(ditf->api);
        nlen = strlen(name);
@@ -112,6 +128,12 @@ static struct afb_req unstore_req_cb(void *closure, struct afb_stored_req *sreq)
 
 static int require_api_cb(void *closure, const char *name, int initialized)
 {
+       struct afb_ditf *ditf = closure;
+       if (ditf->state != Daemon_Init) {
+               ERROR("[API %s] Bad call to 'afb_daemon_require(%s, %d)', must be in Init", ditf->api, name, initialized);
+               errno = EINVAL;
+               return -1;
+       }
        return -!(initialized ? afb_apiset_lookup_started : afb_apiset_lookup)(main_apiset, name, 1);
 }
 
@@ -246,6 +268,7 @@ static const struct afb_daemon_itf hooked_daemon_itf = {
 void afb_ditf_init_v2(struct afb_ditf *ditf, const char *api, struct afb_binding_data_v2 *data)
 {
        ditf->version = 2;
+       ditf->state = Daemon_Pre_Init;
        ditf->v2 = data;
        data->daemon.closure = ditf;
        afb_ditf_rename(ditf, api);
@@ -254,6 +277,7 @@ void afb_ditf_init_v2(struct afb_ditf *ditf, const char *api, struct afb_binding
 void afb_ditf_init_v1(struct afb_ditf *ditf, const char *api, struct afb_binding_interface_v1 *itf)
 {
        ditf->version = 1;
+       ditf->state = Daemon_Pre_Init;
        ditf->v1 = itf;
        itf->verbosity = verbosity;
        itf->mode = AFB_MODE_LOCAL;
index 5b8dbf5..a24eb0a 100644 (file)
 struct afb_binding_interface_v1;
 struct afb_binding_data_v2;
 
+enum afb_ditf_state
+{
+       Daemon_Pre_Init,
+       Daemon_Init,
+       Daemon_Run
+};
+
 struct afb_ditf
 {
        int version;
+       enum afb_ditf_state state;
        const char *api;
        union {
                struct afb_binding_interface_v1 *v1;