From: José Bollo Date: Mon, 4 Sep 2017 11:44:59 +0000 (+0200) Subject: afb-ditf: track daemon state X-Git-Tag: eel/4.99.1~12 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=src%2Fapp-framework-binder.git;a=commitdiff_plain;h=36c7ab15e79d6b0ff6188b61da1061f36b902f8e afb-ditf: track daemon state Change-Id: Ic21c79dcd9908919a1a8d13e8747ef0bd2490477 Signed-off-by: José Bollo --- diff --git a/docs/afb-binding-references.md b/docs/afb-binding-references.md index e340d6b5..c266c2ef 100644 --- a/docs/afb-binding-references.md +++ b/docs/afb-binding-references.md @@ -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) diff --git a/include/afb/afb-daemon-v1.h b/include/afb/afb-daemon-v1.h index 8f5ed2f9..81cdb124 100644 --- a/include/afb/afb-daemon-v1.h +++ b/include/afb/afb-daemon-v1.h @@ -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) diff --git a/include/afb/afb-daemon-v2.h b/include/afb/afb-daemon-v2.h index 481d3dec..7ef085b0 100644 --- a/include/afb/afb-daemon-v2.h +++ b/include/afb/afb-daemon-v2.h @@ -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) diff --git a/src/afb-api-so-v1.c b/src/afb-api-so-v1.c index 2a5dc08a..a341dac3 100644 --- a/src/afb-api-so-v1.c +++ b/src/afb-api-so-v1.c @@ -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; } diff --git a/src/afb-api-so-v2.c b/src/afb-api-so-v2.c index 871be524..49fac6b6 100644 --- a/src/afb-api-so-v2.c +++ b/src/afb-api-so-v2.c @@ -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; } diff --git a/src/afb-ditf.c b/src/afb-ditf.c index 3fc09e92..28cd46a7 100644 --- a/src/afb-ditf.c +++ b/src/afb-ditf.c @@ -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; diff --git a/src/afb-ditf.h b/src/afb-ditf.h index 5b8dbf5a..a24eb0ae 100644 --- a/src/afb-ditf.h +++ b/src/afb-ditf.h @@ -20,9 +20,17 @@ 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;