Add 'afb_daemon_require_api'
authorJosé Bollo <jose.bollo@iot.bzh>
Fri, 2 Jun 2017 07:13:06 +0000 (09:13 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Fri, 2 Jun 2017 15:05:37 +0000 (17:05 +0200)
This solution is at this time the best one to allow
asynchronous calls within initialisation of bindings.

Change-Id: I21ba3a74b4e93eec238a11dd51bc6b58c483308d
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
include/afb/afb-binding.h
include/afb/afb-daemon-common.h
include/afb/afb-daemon-v1.h
include/afb/afb-daemon-v2.h
src/afb-ditf.c
src/afb-hook.c
src/afb-hook.h

index 706ca81..ae700f4 100644 (file)
@@ -163,6 +163,7 @@ typedef struct afb_service_itf          afb_service_itf;
 #define afb_daemon_rootdir_get_fd      afb_daemon_rootdir_get_fd_v1
 #define afb_daemon_rootdir_open_locale afb_daemon_rootdir_open_locale_v1
 #define afb_daemon_queue_job           afb_daemon_queue_job_v1
+#define afb_daemon_require_api         afb_daemon_require_api_v1
 
 #define afb_service_call               afb_service_call_v1
 #define afb_service_call_sync          afb_service_call_sync_v1
@@ -217,6 +218,7 @@ typedef struct afb_service_itf          afb_service_itf;
 #define afb_daemon_rootdir_open_locale afb_daemon_rootdir_open_locale_v2
 #define afb_daemon_queue_job           afb_daemon_queue_job_v2
 #define afb_daemon_unstore_req         afb_daemon_unstore_req_v2
+#define afb_daemon_require_api         afb_daemon_require_api_v2
 
 #define afb_service_call               afb_service_call_v2
 #define afb_service_call_sync          afb_service_call_sync_v2
index d3d1b3d..1d576b9 100644 (file)
@@ -41,6 +41,7 @@ struct afb_daemon_itf
        int (*queue_job)(void *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout);
        void (*vverbose_v2)(void*closure, int level, const char *file, int line, const char * func, const char *fmt, va_list args);
        struct afb_req (*unstore_req)(void*closure, struct afb_stored_req *sreq);
+       int (*require_api)(void*closure, const char *name, int initialized);
 };
 
 /*
index 256c5fd..8f5ed2f 100644 (file)
@@ -163,3 +163,13 @@ static inline int afb_daemon_queue_job_v1(struct afb_daemon daemon, void (*callb
 {
        return daemon.itf->queue_job(daemon.closure, callback, argument, group, timeout);
 }
+
+/*
+ * Tells that it requires the API of "name" to exist
+ * and if 'initialized' is not null to be initialized.
+ * 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)
+{
+       return daemon.itf->require_api(daemon.closure, name, initialized);
+}
index 4c4c656..481d3de 100644 (file)
@@ -141,3 +141,12 @@ static inline struct afb_req afb_daemon_unstore_req_v2(struct afb_stored_req *sr
        return afb_get_daemon_v2().itf->unstore_req(afb_get_daemon_v2().closure, sreq);
 }
 
+/*
+ * Tells that it requires the API of "name" to exist
+ * and if 'initialized' is not null to be initialized.
+ * 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)
+{
+       return afb_get_daemon_v2().itf->require_api(afb_get_daemon_v2().closure, name, initialized);
+}
index 6613676..66bdb9d 100644 (file)
 #include "afb-evt.h"
 #include "afb-common.h"
 #include "afb-xreq.h"
+#include "afb-api.h"
+#include "afb-apiset.h"
 #include "afb-hook.h"
 #include "jobs.h"
 #include "verbose.h"
 
+extern struct afb_apiset *main_apiset;
+
 /**********************************************
 * normal flow
 **********************************************/
@@ -106,6 +110,12 @@ static struct afb_req unstore_req_cb(void *closure, struct afb_stored_req *sreq)
        return afb_xreq_unstore(sreq);
 }
 
+static int require_api_cb(void *closure, const char *name, int initialized)
+{
+       struct afb_api a;
+       return (initialized ? afb_apiset_get_started : afb_apiset_get)(main_apiset, name, &a);
+}
+
 /**********************************************
 * hooked flow
 **********************************************/
@@ -192,6 +202,15 @@ static struct afb_req hooked_unstore_req_cb(void *closure, struct afb_stored_req
        return unstore_req_cb(closure, sreq);
 }
 
+static int hooked_require_api_cb(void *closure, const char *name, int initialized)
+{
+       int result;
+       struct afb_ditf *ditf = closure;
+       afb_hook_ditf_require_api(ditf, name, initialized);
+       result = require_api_cb(closure, name, initialized);
+       return afb_hook_ditf_require_api_result(ditf, name, initialized, result);
+}
+
 /**********************************************
 * vectors
 **********************************************/
@@ -206,7 +225,8 @@ static const struct afb_daemon_itf daemon_itf = {
        .rootdir_get_fd = afb_common_rootdir_get_fd,
        .rootdir_open_locale = rootdir_open_locale_cb,
        .queue_job = queue_job_cb,
-       .unstore_req = unstore_req_cb
+       .unstore_req = unstore_req_cb,
+       .require_api = require_api_cb
 };
 
 static const struct afb_daemon_itf hooked_daemon_itf = {
@@ -220,7 +240,8 @@ static const struct afb_daemon_itf hooked_daemon_itf = {
        .rootdir_get_fd = hooked_rootdir_get_fd,
        .rootdir_open_locale = hooked_rootdir_open_locale_cb,
        .queue_job = hooked_queue_job_cb,
-       .unstore_req = hooked_unstore_req_cb
+       .unstore_req = hooked_unstore_req_cb,
+       .require_api = hooked_require_api_cb
 };
 
 void afb_ditf_init_v2(struct afb_ditf *ditf, const char *api, struct afb_binding_data_v2 *data)
index bf90732..2f101bf 100644 (file)
@@ -647,6 +647,16 @@ static void hook_ditf_unstore_req_cb(void * closure,  const struct afb_ditf *dit
        _hook_ditf_(ditf, "unstore_req(%p)", sreq);
 }
 
+static void hook_ditf_require_api_cb(void *closure, const struct afb_ditf *ditf, const char *name, int initialized)
+{
+       _hook_ditf_(ditf, "require_api(%s, %d)...", name, initialized);
+}
+
+static void hook_ditf_require_api_result_cb(void *closure, const struct afb_ditf *ditf, const char *name, int initialized, int result)
+{
+       _hook_ditf_(ditf, "...require_api(%s, %d) -> %d", name, initialized, result);
+}
+
 static struct afb_hook_ditf_itf hook_ditf_default_itf = {
        .hook_ditf_event_broadcast_before = hook_ditf_event_broadcast_before_cb,
        .hook_ditf_event_broadcast_after = hook_ditf_event_broadcast_after_cb,
@@ -658,7 +668,9 @@ static struct afb_hook_ditf_itf hook_ditf_default_itf = {
        .hook_ditf_rootdir_get_fd = hook_ditf_rootdir_get_fd_cb,
        .hook_ditf_rootdir_open_locale = hook_ditf_rootdir_open_locale_cb,
        .hook_ditf_queue_job = hook_ditf_queue_job_cb,
-       .hook_ditf_unstore_req = hook_ditf_unstore_req_cb
+       .hook_ditf_unstore_req = hook_ditf_unstore_req_cb,
+       .hook_ditf_require_api = hook_ditf_require_api_cb,
+       .hook_ditf_require_api_result = hook_ditf_require_api_result_cb
 };
 
 /******************************************************************************
@@ -742,6 +754,17 @@ void afb_hook_ditf_unstore_req(const struct afb_ditf *ditf, struct afb_stored_re
        _HOOK_DITF_(unstore_req, ditf, sreq);
 }
 
+void afb_hook_ditf_require_api(const struct afb_ditf *ditf, const char *name, int initialized)
+{
+       _HOOK_DITF_(require_api, ditf, name, initialized);
+}
+
+int afb_hook_ditf_require_api_result(const struct afb_ditf *ditf, const char *name, int initialized, int result)
+{
+       _HOOK_DITF_(require_api_result, ditf, name, initialized, result);
+       return result;
+}
+
 /******************************************************************************
  * section: hooking ditf
  *****************************************************************************/
index 4070021..8e6fae3 100644 (file)
@@ -150,6 +150,8 @@ extern void afb_hook_xreq_unstore(const struct afb_xreq *xreq);
 #define afb_hook_flag_ditf_rootdir_open_locale         0x000100
 #define afb_hook_flag_ditf_queue_job                   0x000200
 #define afb_hook_flag_ditf_unstore_req                 0x000400
+#define afb_hook_flag_ditf_require_api                 0x000800
+#define afb_hook_flag_ditf_require_api_result          0x001000
 
 #define afb_hook_flags_ditf_common     (afb_hook_flag_ditf_vverbose\
                                        |afb_hook_flag_ditf_event_make\
@@ -161,7 +163,9 @@ extern void afb_hook_xreq_unstore(const struct afb_xreq *xreq);
                                        |afb_hook_flag_ditf_rootdir_get_fd\
                                        |afb_hook_flag_ditf_rootdir_open_locale\
                                        |afb_hook_flag_ditf_queue_job\
-                                       |afb_hook_flag_ditf_unstore_req)
+                                       |afb_hook_flag_ditf_unstore_req\
+                                       |afb_hook_flag_ditf_require_api\
+                                       |afb_hook_flag_ditf_require_api_result)
 
 #define afb_hook_flags_ditf_all                (afb_hook_flags_ditf_common|afb_hook_flags_ditf_extra)
 
@@ -177,6 +181,8 @@ struct afb_hook_ditf_itf {
        void (*hook_ditf_rootdir_open_locale)(void *closure, const struct afb_ditf *ditf, const char *filename, int flags, const char *locale, int result);
        void (*hook_ditf_queue_job)(void *closure, const struct afb_ditf *ditf, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result);
        void (*hook_ditf_unstore_req)(void *closure, const struct afb_ditf *ditf, struct afb_stored_req *sreq);
+       void (*hook_ditf_require_api)(void *closure, const struct afb_ditf *ditf, const char *name, int initialized);
+       void (*hook_ditf_require_api_result)(void *closure, const struct afb_ditf *ditf, const char *name, int initialized, int result);
 };
 
 extern void afb_hook_ditf_event_broadcast_before(const struct afb_ditf *ditf, const char *name, struct json_object *object);
@@ -190,6 +196,8 @@ extern int afb_hook_ditf_rootdir_get_fd(const struct afb_ditf *ditf, int result)
 extern int afb_hook_ditf_rootdir_open_locale(const struct afb_ditf *ditf, const char *filename, int flags, const char *locale, int result);
 extern int afb_hook_ditf_queue_job(const struct afb_ditf *ditf, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result);
 extern void afb_hook_ditf_unstore_req(const struct afb_ditf *ditf, struct afb_stored_req *sreq);
+extern void afb_hook_ditf_require_api(const struct afb_ditf *ditf, const char *name, int initialized);
+extern int afb_hook_ditf_require_api_result(const struct afb_ditf *ditf, const char *name, int initialized, int result);
 
 extern int afb_hook_flags_ditf(const char *api);
 extern struct afb_hook_ditf *afb_hook_create_ditf(const char *api, int flags, struct afb_hook_ditf_itf *itf, void *closure);