Ensure that subcall_sync use subcall
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 4 Apr 2017 15:30:55 +0000 (17:30 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Tue, 4 Apr 2017 15:30:55 +0000 (17:30 +0200)
The intent is to provide the asynchronous subcall
as standard. This is needed for fixing subcall
across connections (DBus or WebSocket).

Change-Id: Ia046cfa4d0124bfa3ba7eb8e8f936eeafcf09875
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/afb-api-so-v1.c
src/afb-api-so-v2.c
src/afb-subcall.c
src/afb-xreq.c
src/afb-xreq.h

index fee6b2e..61b646a 100644 (file)
@@ -144,12 +144,8 @@ static void call_cb(void *closure, struct afb_xreq *xreq)
        verb = search(desc, xreq->verb);
        if (!verb)
                afb_xreq_fail_f(xreq, "unknown-verb", "verb %s unknown within api %s", xreq->verb, desc->binding->v1.prefix);
-       else {
-               xreq->sessionflags = (int)verb->session;
-               xreq->group = desc;
-               xreq->callback = verb->callback;
-               afb_xreq_call(xreq);
-       }
+       else
+               afb_xreq_call(xreq, verb->session, verb->callback);
 }
 
 static int service_start_cb(void *closure, int share_session, int onneed)
index 75e59d6..4e34e03 100644 (file)
@@ -142,12 +142,8 @@ static void call_cb(void *closure, struct afb_xreq *xreq)
        verb = search(desc, xreq->verb);
        if (!verb)
                afb_xreq_fail_f(xreq, "unknown-verb", "verb %s unknown within api %s", xreq->verb, desc->binding->api);
-       else {
-               xreq->sessionflags = (int)verb->session;
-               xreq->group = desc;
-               xreq->callback = verb->callback;
-               afb_xreq_call(xreq);
-       }
+       else
+               afb_xreq_call(xreq, verb->session, verb->callback);
 }
 
 static int service_start_cb(void *closure, int share_session, int onneed)
index bc5fc86..b586e28 100644 (file)
@@ -37,7 +37,6 @@ static void subcall_destroy(void *closure);
 static void subcall_reply(void *closure, int iserror, struct json_object *obj);
 static int subcall_subscribe(void *closure, struct afb_event event);
 static int subcall_unsubscribe(void *closure, struct afb_event event);
-static void subcall_sync_leave(struct subcall *subcall);
 
 const struct afb_xreq_query_itf afb_subcall_xreq_itf = {
        .reply = subcall_reply,
@@ -52,9 +51,6 @@ struct subcall
        struct afb_xreq *caller;
        void (*callback)(void*, int, struct json_object*);
        void *closure;
-       struct jobloop *jobloop;
-       struct json_object *result;
-       int iserror;
 };
 
 static void subcall_destroy(void *closure)
@@ -70,14 +66,8 @@ static void subcall_reply(void *closure, int iserror, struct json_object *obj)
 {
        struct subcall *subcall = closure;
 
-       if (subcall->callback) {
-               subcall->callback(subcall->closure, iserror, obj);
-               json_object_put(obj);
-       } else {
-               subcall->result = obj;
-               subcall->iserror = iserror;
-               subcall_sync_leave(subcall);
-       }
+       subcall->callback(subcall->closure, iserror, obj);
+       json_object_put(obj);
 }
 
 static int subcall_subscribe(void *closure, struct afb_event event)
@@ -139,25 +129,47 @@ void afb_subcall(
        afb_xreq_unref(&subcall->xreq);
 }
 
-static void subcall_sync_leave(struct subcall *subcall)
+struct subcall_sync
 {
-       struct jobloop *jobloop = subcall->jobloop;
-       subcall->jobloop = NULL;
+       struct afb_xreq *caller;
+       const char *api;
+       const char *verb;
+       struct json_object *args;
+       struct jobloop *jobloop;
+       struct json_object *result;
+       int iserror;
+};
+
+static void subcall_sync_leave(struct subcall_sync *sync)
+{
+       struct jobloop *jobloop = sync->jobloop;
+       sync->jobloop = NULL;
        if (jobloop)
                jobs_leave(jobloop);
 }
 
-static void subcall_sync_cb(int signum, void *closure, struct jobloop *jobloop)
+static void subcall_sync_reply(void *closure, int iserror, struct json_object *obj)
 {
-       struct subcall *subcall = closure;
+       struct subcall_sync *sync = closure;
+
+       sync->iserror = iserror;
+       sync->result = obj;
+       json_object_get(obj);
+       subcall_sync_leave(sync);
+}
+
+static void subcall_sync_enter(int signum, void *closure, struct jobloop *jobloop)
+{
+       struct subcall_sync *sync = closure;
 
        if (!signum) {
-               subcall->jobloop = jobloop;
-               afb_apis_call_direct(&subcall->xreq);
+               sync->jobloop = jobloop;
+               afb_xreq_subcall(sync->caller, sync->api, sync->verb, sync->args, subcall_sync_reply, sync);
        } else {
-               afb_xreq_fail_f(&subcall->xreq, "aborted", "signal %s(%d) caught", strsignal(signum), signum);
+               sync->result = json_object_get(afb_msg_json_internal_error());
+               sync->iserror = 1;
+               subcall_sync_leave(sync);
        }
-       subcall_sync_leave(subcall);
 }
 
 int afb_subcall_sync(
@@ -169,22 +181,23 @@ int afb_subcall_sync(
 )
 {
        int rc;
-       struct subcall *subcall;
+       struct subcall_sync sync;
 
-       subcall = create_subcall(caller, api, verb, args, NULL, NULL);
-       if (subcall == NULL) {
-               *result = json_object_get(afb_msg_json_internal_error());
-               return 0;
-       }
+       sync.caller = caller;
+       sync.api = api;
+       sync.verb = verb;
+       sync.args = args;
+       sync.jobloop = NULL;
+       sync.result = NULL;
+       sync.iserror = 1;
 
-       rc = jobs_enter(NULL, 0, subcall_sync_cb, subcall);
+       rc = jobs_enter(NULL, 0, subcall_sync_enter, &sync);
        if (rc < 0) {
-               subcall->result = json_object_get(afb_msg_json_internal_error());
-               subcall->iserror = 1;
+               sync.result = json_object_get(afb_msg_json_internal_error());
+               sync.iserror = 1;
        }
-       rc = !subcall->iserror;
-       *result = subcall->result;
-       afb_xreq_unref(&subcall->xreq);
+       rc = !sync.iserror;
+       *result = sync.result;
        return rc;
 }
 
index 15ebae0..b64cefb 100644 (file)
@@ -250,6 +250,12 @@ int afb_xreq_unsubscribe(struct afb_xreq *xreq, struct afb_event event)
 static void xreq_subcall_cb(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure)
 {
        struct afb_xreq *xreq = closure;
+
+       afb_xreq_subcall(xreq, api, verb, args, callback, cb_closure);
+}
+
+void afb_xreq_subcall(struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure)
+{
        if (xreq->queryitf->subcall)
                xreq->queryitf->subcall(xreq->query, api, verb, args, callback, cb_closure);
        else
@@ -259,12 +265,7 @@ static void xreq_subcall_cb(void *closure, const char *api, const char *verb, st
 static int xreq_subcallsync_cb(void *closure, const char *api, const char *verb, struct json_object *args, struct json_object **result)
 {
        struct afb_xreq *xreq = closure;
-/*
-       if (xreq->queryitf->subcallsync)
-               xreq->queryitf->subcall(xreq->query, api, verb, args, callback, cb_closure);
-       else
-*/
-               return afb_subcall_sync(xreq, api, verb, args, result);
+       return afb_subcall_sync(xreq, api, verb, args, result);
 }
 
 void afb_xreq_success_f(struct afb_xreq *xreq, struct json_object *obj, const char *info, ...)
@@ -291,10 +292,8 @@ void afb_xreq_fail_f(struct afb_xreq *xreq, const char *status, const char *info
        free(message);
 }
 
-static int xcheck(struct afb_xreq *xreq)
+static int xcheck(struct afb_xreq *xreq, int stag)
 {
-       int stag = xreq->sessionflags;
-
        if ((stag & (AFB_SESSION_CREATE|AFB_SESSION_CLOSE|AFB_SESSION_RENEW|AFB_SESSION_CHECK|AFB_SESSION_LOA_EQ)) != 0) {
                if (!afb_context_check(&xreq->context)) {
                        afb_context_close(&xreq->context);
@@ -338,9 +337,9 @@ static int xcheck(struct afb_xreq *xreq)
        return 1;
 }
 
-void afb_xreq_call(struct afb_xreq *xreq)
+void afb_xreq_call(struct afb_xreq *xreq, int sessionflags, void (*callback)(struct afb_req req))
 {
-       if (xcheck(xreq))
-               xreq->callback((struct afb_req){ .itf = &xreq_itf, .closure = xreq });
+       if (xcheck(xreq, sessionflags))
+               callback((struct afb_req){ .itf = &xreq_itf, .closure = xreq });
 }
 
index 29dcb3e..3413703 100644 (file)
@@ -52,10 +52,6 @@ struct afb_xreq
        const struct afb_xreq_query_itf *queryitf;
        int refcount;   /**< current ref count */
        int replied;    /**< is replied? */
-       int timeout;    /**< timeout */
-       int sessionflags; /**< flags to check */
-       void *group;
-       void (*callback)(struct afb_req req);
        struct afb_evt_listener *listener;
 };
 
@@ -68,6 +64,7 @@ extern void afb_xreq_success_f(struct afb_xreq *xreq, struct json_object *obj, c
 extern const char *afb_xreq_raw(struct afb_xreq *xreq, size_t *size);
 extern int afb_xreq_subscribe(struct afb_xreq *xreq, struct afb_event event);
 extern int afb_xreq_unsubscribe(struct afb_xreq *xreq, struct afb_event event);
+extern void afb_xreq_subcall(struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure);
 
-extern void afb_xreq_call(struct afb_xreq *xreq);
+extern void afb_xreq_call(struct afb_xreq *xreq, int sessionflags, void (*callback)(struct afb_req req));